답변:
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
. 두 번째 테이블은 정확히 하나의 행과 하나의 열로 가상 테이블을 "만들고"외부 조인 ( "실제"조인 조건없이)을 수행하므로 항상 하나 이상의 행을 다시 가져옵니다. select *
프로덕션 코드에서 사용 하는 것은 좋지 않습니다. 하지마 항상 필요한 열을 나열하십시오. 임시 쿼리 에서만select *
사용해야 합니다.
left join
읽을 수 없다고 생각 합니까?
UNION ALL
보다 효율적일 UNION
수 있습니다. UNION
그것들이 출력되기를 원합니다. ALL
수정자를 사용 하지 않으면 DISTINCT
키워드 와 같은 방식으로 중복 행을 제거하고 (각 반환 된 항목 중 하나만) 중복 된 결과를 원한다고 가정 하고 추가 시간에 결과를 다시 작성해야합니다. 따라서 출력 행 중복 제거가 특별히 필요한 경우 ALL
가 UNION
아니면 함께 사용하십시오 .
하나 또는 0 개의 행만 다시 기대하면 다음과 같이 작동합니다.
SELECT
max(col1) col1,
max(col2) col2,
1 AS query_id
FROM
players
WHERE
username='foobar';
행이 없으면 query_id를 제외한 모든 값이 null 인 행 하나를 반환합니다.
username = 'foobar'
여기 늦게 Chiming하지만 작동하는 구문이 있습니다 (적어도 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 인 경우 "공백"행만 반환합니다.
즐겨. / 비트 헤드