Considérez cette instruction select:
SELECT *,
1 AS query_id
FROM players
WHERE username='foobar';
Il renvoie la colonne query_id
avec une valeur 1
ainsi que les autres colonnes d'un joueur.
Comment faire pour que le SQL ci-dessus renvoie au moins le query_id
de 1
même si la sélection ne trouve aucune ligne correspondant?
BTW, c'est PostgreSQL 8.4.
SELECT col1,
col2,
col3,
1 AS query_id
FROM players
WHERE username='foobar'
union all
select null,
null,
null,
1
where not exists (select 1 from players where username = 'foobar');
Ou comme alternative (pourrait être plus rapide car aucune seconde sous-sélection n'est requise):
with qid (query_id) as (
values (1)
)
select p.*,
qid.query_id
from qid
left join players as p on (p.useranme = 'foobar');
Vous pouvez réécrire ce qui précède dans une représentation plus "compacte":
select p.*,
qid.query_id
from (values (1)) as qid (query_id)
left join players as p on (p.useranme = 'foobar');
Mais je pense que le CTE explicite (with...
) est plus lisible (bien que ce soit toujours aux yeux du spectateur).
Si vous ne vous attendez qu'à une ou zéro ligne, cela fonctionnera également:
SELECT
max(col1) col1,
max(col2) col2,
1 AS query_id
FROM
players
WHERE
username='foobar';
Cela retournera une ligne avec toutes les valeurs ayant null sauf query_id si aucune ligne n'est trouvée.
Sonner de manière tardive ici, mais voici une syntaxe qui fonctionne (au moins dans 9.2, je n'ai pas essayé les versions antérieures).
SELECT (COALESCE(a.*,b.*::players)).*
FROM ( SELECT col1, col2, col3, 1 AS query_id
FROM players WHERE username='foobar' ) a
RIGHT JOIN (select null col1, null col2, null col3, 1 col4) b
ON a.query_id = b.col4;
Renvoie la ligne "vide" uniquement si le contenu entier de "a" est nul.
Prendre plaisir./bithead