回答:
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');
または代替として(かもしれない何秒副選択が必要とされないよう速くなります)。
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...
)の方が読みやすいと思います(ただし、それは常に見る人の目にあります)。
order by
。2番目は、正確に1行1列で仮想テーブルを「作成」し、外部結合を(「実際の」結合条件なしで)実行するため、少なくともその1行が常に返されます。select *
本番コードでの使用はスタイルが悪いです。しないでください。常に必要な列をリストしてください。 アドホッククエリでのみ使用するselect *
必要があります。
left join
は読めないと思いますか?
UNION ALL
時々よりも効率的な場合がありUNION
ますが、明示的にどちらかあなたが出てくる重複行が存在しないことを期待することを問い合わせプランナを言っているように、UNION
エドクエリまたは場合それらを出力したいのです。ALL
修飾子なしでは、DISTINCT
キーワードと同じように(返される各行の1つだけ)重複行を削除することを前提とし、結果をさらに時間をかけて再スキャンする必要があることを保証します。したがって、出力行の重複排除が特に必要ALL
でUNION
ない限り、withを使用します。
1行または0行しか戻らないことを期待している場合、これも機能します。
SELECT
max(col1) col1,
max(col2) col2,
1 AS query_id
FROM
players
WHERE
username='foobar';
行が見つからない場合、query_idを除くすべての値がnullである1つの行を返します。
username = 'foobar'
ここで遅く鳴りますが、動作する構文があります(少なくとも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」の内容全体がヌルの場合にのみ、「ブランク」行を返します。
楽しい。/ bithead