web-dev-qa-db-ja.com

ゼロ行が一致する場合でもSELECTが定数値を返すようにする

次のselectステートメントを検討してください。

SELECT *, 
       1 AS query_id 
FROM players 
WHERE username='foobar';

query_idと値1をプレーヤーの他の列とともに返します。

Selectで一致する行が見つからない場合でも、上記のSQLで少なくともquery_id1を返すにはどうすればよいですか?

ところで、それは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');

または、代替として(might 2番目の副選択が必要ないため、より高速になります):

with qid (query_id) as (
   values (1)
) 
select p.*, 
       qid.query_id
from qid 
  left join players as p on (p.useranme = 'foobar');

上記をより「コンパクトな」表現に書き直すことができます。

select p.*, 
       qid.query_id
from (values (1)) as qid (query_id)
  left join players as p on (p.useranme = 'foobar');

しかし、私は明示的なCTE(with...)はより読みやすくなっています(ただし、それは常に見る人の目にはあります)。

22

1行または0行だけが返されることを期待している場合、これも機能します。

SELECT
  max(col1) col1,
  max(col2) col2, 
  1 AS query_id 
FROM
  players 
WHERE
  username='foobar';

これは、行が見つからない場合のquery_idを除き、すべての値がnullである1行を返します。

7
David Aldridge

ここで遅いタイミングで鳴りますが、これは機能する構文です(少なくとも9.2では、以前のバージョンを試していません)。

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;

「a」の内容全体がnullの場合にのみ「空白」行を返します。

楽しい。/bithead

3
Kirk Roybal