ORDER BY com uma união de conjuntos de dados díspares (T-SQL)
-
05-07-2019 - |
Pergunta
Eu tenho uma consulta que dois conjuntos de dados um pouco semelhante de UNION
, mas ambos têm algumas colunas que não estão presentes no outro (ou seja, as colunas têm valores nulos na UNION
resultante.)
O problema é, eu preciso ORDER
os dados resultantes utilizando as colunas que só existem em um ou o outro conjunto, para obter os dados em um formato amigável para o lado do software a.
Por exemplo: Tabela 1 tem campos ID, Cat, Price
. Table2 tem campos ID, Name, Abbrv
. O campo ID
é comum entre as duas tabelas.
minha consulta parece com algo como isto:
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
O ORDER BY
é onde eu estou preso. Os olhares de dados como este:
100 Balls 1.53
200 Bubbles 1.24
100 RedBall 101RB
100 BlueBall 102BB
200 RedWand 201RW
200 BlueWand 202BW
... mas eu quero que ele se parece com isto:
100 Balls 1.53
100 RedBall 101RB
100 BlueBall 102BB
200 Bubbles 1.24
200 RedWand 201RW
200 BlueWand 202BW
Eu estou esperando que isso pode ser feito em T-SQL.
Solução
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
De alguma forma você tem que saber os dados na tabela 2 estão ligadas a tabela 1 e compartilhar o preço. Desde o nulo no abbrv vai vir em primeiro lugar, não há necessidade de criar uma coluna SortAbbrv.
Outras dicas
Você deve usar UNION ALL em vez de UNION para economizar o custo de verificação de duplicata.
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
Uma solução rápida seria fazer 2 inserções em uma tabela temporária ou uma variável de tabela e como parte de inserção na tabela de temperatura você pode definir uma coluna de bandeira para ajuda com a classificação e, em seguida, ordem por essa coluna da bandeira.
Em cima da minha cabeça, eu diria que o pior cenário é você criar uma tabela temporária com todos os campos que um INSERT INTO tabela temporária de ambos T1 & T2 em seguida, selecione a tabela temporária com uma ordem de.
ie. Criar uma tabela temporária (por exemplo #temp.) Com campos Id, gato, Preço, nome, abbrv, e depois:
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: Eu não estou 100% certo sobre a sintaxe nulo das inserções, mas eu acho que vai funcionar
.EDIT: Adicionado ordenação por Preço & abbrv após id ... se Id não link T1 & T2, então o que faz