SQL nella clausola con righe fittizie
-
01-10-2019 - |
Domanda
Mi piacerebbe davvero sapere se è possibile fare una dichiarazione prescelta, che restituisce esattamente stessi record, che abbiamo messo in clausola?
Esempio:
select * from table
where table_id in (1, 2, 3, 666);
Questa tabella, che ha solo id-s da 1 a 100, quindi questo selezionare torneranno solo tre righe. Cosa devo fare, per ottenere anche uno (probabilmente nulla o fittizio) riga per 666?
Grazie!
Soluzione
Si potrebbe usare l'unione:
select * from table
where table_id in (1, 2, 3);
union
select 666 as table_id, other_fields_with_dummy_values_in_table from dual;
Ecco come si potesse fare in Oracle. Il from dual
può variare a seconda del sistema di database che si sta utilizzando.
Basta essere consapevoli del fatto che se si utilizza l'unione, la query manichino necessario selezionare lo stesso record come il vero query.
Altri suggerimenti
È possibile selezionare senza una tabella
Basta fare un UNION con la query
select table_id, some_column from table
where table_id in (1, 2, 3, 666);
union
select 666, 'dummy_data'
Supponendo un numbers
tabella contenente tutti i numeri da, diciamo, 1-1.000.000 (infatti sufficiente che la vostra gamma di valori di ingresso è coperto), è possibile eseguire il seguente SQL:
SELECT *
FROM numbers left outer join table on table.table_id = numbers.number
WHERE numbers.number in (1, 2, 3, 666)
Se si utilizza un DBMS che offre una soluzione migliore, come e. g. SQL Anywhere con esso è procedura sa_rowgenerator , è possibile sostituire il numbers
tavolo con una chiamata di procedura, e non hanno un limite di un numero massimo.
clausola IN
è un predicato booleano, quindi sarà necessario sostituirlo con un set di record dummy:
SELECT m.*
FROM (
SELECT 1 AS id
UNION ALL
SELECT 2 AS id
UNION ALL
SELECT 3 AS id
UNION ALL
SELECT 666 AS id
) q
LEFT JOIN
mytable m
ON m.id = q.id
In SQL Server 2008
, è possibile eseguire questa query:
SELECT *
FROM @mydata d
LEFT JOIN
mytable t
ON t.id = d.id
con @mydate
è una variabile di tabella, passato come parametro dal client.
In PostgreSQL
, è possibile eseguire questa query:
SELECT *
FROM (
SELECT :arr[s] AS id
FROM generate_series(1, array_upper(:arr, 1)) s
) q
LEFT JOIN
mytable t
ON t.id = q.id
dove :arr
è un [1, 2, 3, 666]
array, superato anche da parte del cliente come parametro.
In Oracle
, si può fare:
SELECT *
FROM TABLE(:mycol) q
LEFT JOIN
mytable t
ON t.id = q.id
, dove :mycol
è un variabile di tipo di raccolta, passata dal client.
Un modo di pensare che è: avresti bisogno di avere che i dati "entrare" la query come un insieme di dati. I dati trovato in cui non è mai "aggiunto" clausole alla query, sono utilizzati solo per filtrare i dati esistenti fuori.
Un esempio veloce:
DECLARE @MustInclude (Value int not null)
INSERT @MustInclude (Value) values (1)
INSERT @MustInclude (Value) values (2)
INSERT @MustInclude (Value) values (3)
INSERT @MustInclude (Value) values (666)
SELECT *
from @MustInclude mi
left outer join MyTable mt
on mt.Value = mi.Value