Разница между 'union' и 'union all' при оценке кода SQL на платформе LMS
У меня проблема с выставлением оценок за упражнение на платформе LMS.
У нас есть два запроса:
select
distinct c.city_name,'city' obj_type
from
shipping.city c
union all
select
distinct c.state,'state' obj_type
from
shipping.city c
union all
select
distinct d.first_name,'driver' obj_type
from
shipping.driver d
union all
select
distinct t.Make,'truck' obj_type
from
shipping.truck t
order by 1 desc
и это:
select
c.city_name,'city' obj_type
from
shipping.city c
union
select
c.state,'state' obj_type
from
shipping.city c
union
select
d.first_name,'driver' obj_type
from
shipping.driver d
union
select
t.Make,'truck' obj_type
from
shipping.truck t
order by 1 desc
Оба дают мне одинаковые результаты, но второй не получает оценок на платформе. В то же время я проверяю результаты с помощью except в Metabase и получаю "Нет результатов!" (значение NULL)
Как работает platfrom:
Он отправляет 2 запроса в базу и проверяет разницу между ответами студента и справочника.
Я думал, что в Metabase может быть рваное представление данных с помощью "union" и "union all", но сравнение с except ничего мне не дало. Спасибо!
UPD: Решите проблему. В двух запросах была разная сортировка, тоже была проверка на платформе, и запросы были разными. Спасибо вам всем!
2 ответа
Проблема состоит в том, что три ноги Союза всегда будет разной, becaus разных констант для {города, штата, водитель, грузовика} буквального. Так что дубликатов не будет, аUNION
дает тот же результат, что и UNION ALL
.
Пример:
-- some data ...
CREATE TABLE one
( num integer not null
, nam text
);
INSERT INTO one ( num , nam ) values (1,'one'), (2, 'two'), (3, 'three');
-- QUERY#1
SELECT 'from_first' AS "origin"
, num, nam
FROM one
UNION
SELECT 'from_second' AS "origin"
, num, nam
FROM one
ORDER BY 1,2
;
-- QUERY#2
SELECT 'from_first' AS "origin"
, num, nam
FROM one
UNION ALL
SELECT 'from_second' AS "origin"
, num, nam
FROM one
ORDER BY 1,2
;
Полученные результаты:
CREATE TABLE
INSERT 0 3
origin | num | nam
-------------+-----+-------
from_first | 1 | one
from_first | 2 | two
from_first | 3 | three
from_second | 1 | one
from_second | 2 | two
from_second | 3 | three
(6 rows)
origin | num | nam
-------------+-----+-------
from_first | 1 | one
from_first | 2 | two
from_first | 3 | three
from_second | 1 | one
from_second | 2 | two
from_second | 3 | three
(6 rows)
Ситуация иная, когда один или два подзапуска сами по себе дают дубликаты, например:
-- some more data ...
CREATE TABLE two
( num integer not null
, nam text
);
INSERT INTO two ( num , nam ) values (1,'one'), (2, 'two'), (2, 'two');
-- QUERY#1a
SELECT 'from_first' AS "origin"
, num, nam
FROM two
UNION
SELECT 'from_second' AS "origin"
, num, nam
FROM two
ORDER BY 1,2
;
-- QUERY#2b
SELECT 'from_first' AS "origin"
, num, nam
FROM two
UNION ALL
SELECT 'from_second' AS "origin"
, num, nam
FROM two
ORDER BY 1,2
;
Результаты2:
CREATE TABLE
INSERT 0 3
origin | num | nam
-------------+-----+-----
from_first | 1 | one
from_first | 2 | two
from_second | 1 | one
from_second | 2 | two
(4 rows)
origin | num | nam
-------------+-----+-----
from_first | 1 | one
from_first | 2 | two
from_first | 2 | two
from_second | 1 | one
from_second | 2 | two
from_second | 2 | two
(6 rows)
Если у вас есть строки в одной таблице с одинаковым значением или сNULL
в city_name
или state
или first_name
или make
результаты могут быть разными.
РЕДАКТИРОВАТЬ: попробуйте проверить свои результаты с помощьюEXCEPT ALL
вместо того EXCEPT
или вы не увидите всех отличий.
Взгляните на этот пример:
DECLARE @T1 TABLE (name VARCHAR(10))
DECLARE @T2 TABLE (surname VARCHAR(10))
DECLARE @R1 TABLE (descr VARCHAR(10), typ VARCHAR(10))
DECLARE @R2 TABLE (descr VARCHAR(10), typ VARCHAR(10))
INSERT INTO @T1
SELECT *
FROM( VALUES ('Abigail'), ('Luke'), ('Mat'), ('Mat'), ('Zoe')) x (d)
INSERT INTO @T2
SELECT *
FROM( VALUES ('Brown'), ('Doe'), ('Doe'), ('Smith'), ('Wilkinson')) x (d)
insert into @r1
select name descr, 'name' descr_type from @t1
union
select surname descr, 'surname' descr_type from @t2
insert into @r2
select name descr, 'name' descr_type from @t1
union all
select surname descr, 'surname' descr_type from @t2
select * from @r1
select * from @r2
Если вы проверите результаты:
select * from @r1
except
select * from @r2
Будет выдавать "Нет результатов!" (значение NULL)
select * from @r1
except all
select * from @r2
Дадим такой результат:
descr typ
'Doe' 'surname'
'Mat' 'name'
Если вы хотите увидеть детали различий:
select *
from
(select ROW_NUMBER() over (partition by descr order by descr) n, * from @r1) r1
full join
(select ROW_NUMBER() over (partition by descr order by descr) n, * from @r2) r2
on r1.n= r2.n and r1.descr = r2.descr