web-dev-qa-db-fra.com

Obtenir SELECT pour renvoyer une valeur constante même si zéro ligne correspond

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.

15
Nathanael Weiss
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).

22

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.

7
David Aldridge

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

3
Kirk Roybal