次のselectステートメントを検討してください。
SELECT *,
1 AS query_id
FROM players
WHERE username='foobar';
列query_id
と値1
をプレーヤーの他の列とともに返します。
Selectで一致する行が見つからない場合でも、上記のSQLで少なくともquery_id
の1
を返すにはどうすればよいですか?
ところで、それは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');
または、代替として(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...
)はより読みやすくなっています(ただし、それは常に見る人の目にはあります)。
1行または0行だけが返されることを期待している場合、これも機能します。
SELECT
max(col1) col1,
max(col2) col2,
1 AS query_id
FROM
players
WHERE
username='foobar';
これは、行が見つからない場合のquery_idを除き、すべての値がnullである1行を返します。
ここで遅いタイミングで鳴りますが、これは機能する構文です(少なくとも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