ORDER BY с СОЮЗОМ разрозненных наборов данных (T-SQL) - PullRequest
15 голосов
/ 17 июня 2009

У меня есть запрос, что UNION - это два несколько похожих набора данных, но у них обоих есть некоторые столбцы, которых нет в другом (то есть столбцы имеют значения NULL в полученном UNION.)

Проблема в том, что мне нужно ORDER результирующих данных, используя те столбцы, которые существуют только в одном или другом наборе, чтобы получить данные в дружественном формате для программного обеспечения.

Например: Таблица1 имеет поля ID, Cat, Price. Таблица2 имеет поля ID, Name, Abbrv. Поле ID является общим для двух таблиц.


Мой запрос выглядит примерно так:

SELECT t1.ID, t1.Cat, t1.Price, NULL as Name, NULL as Abbrv FROM t1 
UNION 
SELECT t2.ID, NULL as Cat, NULL as Price, t2.Name, t2.Abbrv FROM t2 
ORDER BY Price DESC, Abbrv ASC 

В ORDER BY я застрял. Данные выглядят так:

100   Balls     1.53                       
200   Bubbles   1.24                       
100                     RedBall    101RB   
100                     BlueBall   102BB   
200                     RedWand    201RW   
200                     BlueWand   202BW   

... но я хочу, чтобы это выглядело так:

100   Balls     1.53                       
100                     RedBall    101RB   
100                     BlueBall   102BB   
200   Bubbles   1.24                       
200                     RedWand    201RW   
200                     BlueWand   202BW   

Я надеюсь, что это можно сделать в T-SQL.

Ответы [ 4 ]

28 голосов
/ 17 июня 2009
Select ID, Cat, Price, Name, Abbrv
From
(SELECT t1.ID, t1.Cat, t1.Price, t1.Price AS SortPrice, NULL as Name, NULL as Abbrv 
FROM t1
UNION
SELECT t2.ID, NULL as Cat, NULL as Price, t1.Price as SortPrice, t2.Name, t2.Abbrv 
   FROM t2
   inner join t1 on t2.id = t1.id
) t3
ORDER BY SortPrice DESC, Abbrv ASC

Каким-то образом вы должны знать, что данные в таблице 2 связаны с таблицей 1 и делятся ценой. Поскольку значение null в abbrv будет первым, создавать столбец SortAbbrv не нужно.

5 голосов
/ 17 июня 2009

Вы должны использовать UNION ALL вместо UNION, чтобы сэкономить на проверке дубликатов.

SELECT *
FROM
(
SELECT t1.ID, t1.Cat, t1.Price, NULL as Name, NULL as Abbrv FROM t1
UNION ALL
SELECT t2.ID, NULL as Cat, NULL as Price, t2.Name, t2.Abbrv FROM t2
) as sub
ORDER BY
  ID,
  CASE WHEN Price is not null THEN 1 ELSE 2 END,
  Price DESC,
  CASE WHEN Abbrv is not null THEN 1 ELSE 2 END,
  Abbrv ASC
1 голос
/ 17 июня 2009

Вдобавок ко всему, я бы сказал, что в худшем случае вы создаете временную таблицу, в которой все поля делают INSERT INTO временную таблицу из T1 и T2, а затем выбирают SEL из временной таблицы с помощью порядка.

т. Создайте временную таблицу (например, #temp) с полями Id, Cat, Price, Name, Abbrv, а затем:

SELECT Id, Cat, Price, null, null INTO #temp FROM T1
SELECT Id, null, null, Name, Abbrv INTO #temp FROM T2
SELECT * FROM #temp ORDER BY Id, Price DESC, Abbrv ASC

NB. Я не уверен на 100% в нулевом синтаксисе вставок, но думаю, что он будет работать.

РЕДАКТИРОВАТЬ: Добавлено упорядочение по цене и Abbrv после идентификатора ... если идентификатор не связывает T1 и T2, то что делает?

1 голос
/ 17 июня 2009

Быстрое решение состоит в том, чтобы сделать 2 вставки во временную таблицу или переменную таблицы, и как часть вставки во временную таблицу вы можете установить столбец флага, чтобы помочь с сортировкой, а затем упорядочить по этому столбцу флага.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...