ВЫБЕРИТЕ СОЮЗ как ОТДЕЛЬНЫЙ - PullRequest
12 голосов
/ 09 января 2012

Как выполнить операцию DISTINCT для одного столбца после выполнения UNION?

T1
--
ID Value 
1  1
2  2
3  3

T2
--
ID Value
1  2
4  4
5  5


Я пытаюсь вернуть таблицу:

ID Value
1  1
2  2
3  3
4  4
5  5

Я пытался:

SELECT DISTINCT ID, Value 
FROM (SELECT*FROM T1 UNION SELECT*FROM T2) AS T3

Это не похоже на работу.

Ответы [ 4 ]

31 голосов
/ 09 января 2012

Почему вы используете подзапрос?Это будет работать:

SELECT * FROM T1
UNION
SELECT * FROM T2

UNION удаляет дубликаты.(UNION ALL нет)

15 голосов
/ 09 января 2012

Насколько я могу сказать, "один столбец distinct" не существует: distinct всегда применяется ко всей записи (если не используется в агрегате, таком как count(distinct name)).Причина этого в том, что SQL не может угадать, какие значения Value оставить вам, а какие отбросить.Это то, что вам нужно определить самостоятельно.

Попробуйте использовать GROUP BY, чтобы гарантировать, что ID не повторяется, и любой агрегат (здесь MIN, как в вашем примере это был выживший минимум), чтобы выбрать конкретное значение Value:

SELECT ID, min(Value) FROM (SELECT * FROM T1 UNION ALL SELECT * FROM T2) AS T3
GROUP BY ID

Должно быть именно то, что вам нужно.То есть это не тот же запрос, и в нем нет distinct, но это запрос, который возвращает то, что показано в примере.

3 голосов
/ 19 апреля 2016

Я думаю, это то, что вы имели в виду:

SELECT * 
  FROM T1
UNION
SELECT * 
  FROM T2 
  WHERE (
    **ID
** NOT IN (SELECT ID FROM T1)
  );
3 голосов
/ 31 июля 2014

Это - даже несмотря на то, что эта ветка устарела - может быть рабочим решением вопроса ОП, даже если его можно считать грязным.

Мы выбираем все кортежи из первой таблицы, затем добавьте (объедините) его с кортежами из второй таблицы, ограниченными теми, у которых нет конкретного поля, сопоставленного в первой таблице.

SELECT * 
  FROM T1
UNION
SELECT * 
  FROM T2 
  WHERE (
    Value NOT IN (SELECT Value FROM T1)
  );
...