Considerare questi tavoli (standard di codice SQL, gira su SQL Server 2008):
WITH A
AS
(
SELECT *
FROM (
VALUES (1),
(2),
(3),
(4),
(5),
(6)
) AS T (col)
),
B
AS
(
SELECT *
FROM (
VALUES (9),
(8),
(7),
(6),
(5),
(4)
) AS T (col)
), ...
L'effetto desiderato è presente per ordinare tavolo A
da col
ascendente, sorta tavolo B
da col
scendendo poi unioning i due, rimuovendo i duplicati, mantenendo l'ordine prima dell'unione e lasciando la tabella A
risultati sul "top" con tabella B
sul "fondo" ad esempio (Codice pesudo)
(
SELECT *
FROM A
ORDER
BY col
)
UNION
(
SELECT *
FROM B
ORDER
BY col DESC
);
Naturalmente, questo non funzionerà in SQL perché non ci può essere un solo ORDER BY
clausola e può essere applicato soltanto alla espressione di tabella di livello superiore (o qualunque sia l'uscita di una query SELECT
è noto come: lo chiamo "resultset").
La prima cosa da affrontare è l'intersezione tra le due tabelle, in questo caso i valori 4
, 5
e 6
. Come deve essere ordinato l'intersezione deve essere specificato nel codice SQL, quindi è auspicabile che anche il progettista lo specifichi! (cioè la persona che fa la domanda, in questo caso).
L'implicazione in questo caso sembrerebbe essere che l'intersezione ("duplicati") devono essere ordinati entro i risultati della tabella A. Pertanto, il gruppo di risultati ordinato dovrebbe essere simile a questo:
VALUES (1), -- A including intersection, ascending
(2), -- A including intersection, ascending
(3), -- A including intersection, ascending
(4), -- A including intersection, ascending
(5), -- A including intersection, ascending
(6), -- A including intersection, ascending
(9), -- B only, descending
(8), -- B only, descending
(7), -- B only, descending
Nota in SQL "top" e "bottom" non hanno un significato inferito e una tabella (diversa da un set di risultati) non ha ordinamenti inerenti. Inoltre (per farla breve) considera che UNION
rimuove le righe duplicate per implicazione e deve essere applicato prima di ORDER BY
. La conclusione deve essere che l'ordinamento di ciascuna tabella deve essere definito in modo esplicito esponendo una/e colonna/i di ordinamento prima dell'unione di. Per questo possiamo usare la funzione con finestra ROW_NUMBER()
ad es.
...
A_ranked
AS
(
SELECT col,
ROW_NUMBER() OVER (ORDER BY col) AS sort_order_1
FROM A -- include the intersection
),
B_ranked
AS
(
SELECT *,
ROW_NUMBER() OVER (ORDER BY col DESC) AS sort_order_1
FROM B
WHERE NOT EXISTS ( -- exclude the intersection
SELECT *
FROM A
WHERE A.col = B.col
)
)
SELECT *, 1 AS sort_order_0
FROM A_ranked
UNION
SELECT *, 2 AS sort_order_0
FROM B_ranked
ORDER BY sort_order_0, sort_order_1;
coSa fornitore SQL è questo? Non credo che lo standard richieda 'UNION ALL' generi qualsiasi cosa - in realtà il fatto che non lo ordina di solito ciò che lo rende una scelta migliore del semplice' UNION' – Romain
@MikaelEriksson: Questo è quello che ha detto l'OP (anche se in un ordine confuso). Vuole fare un UNION ma non ha l'ordinamento implicito. – mwan
@mwan - Hai ragione. Ho letto male la domanda. –