我有那样的表:
table:
| id | fkey | label | amount |
|----|------|-------|--------|
| 1 | 1 | aaa | 10 |
| 2 | 1 | bbb | 15 |
| 3 | 1 | fff | 99 |
| 4 | 1 | jjj | 33 |
| 5 | 2 | fff | 10 |
fkey
是其他表的外键。
现在我需要查询与某些标签相关的所有金额(' bbb',' eee' fff')和指定的fkey,但是我需要使用NULL
保留所有未标记的标签。
对于WHERE IN ('bbb', 'eee', 'fff')
的简单查询,我当然只有两行:
SELECT label, amount FROM table WHERE label IN ('bbb', 'eee', 'fff') AND fkey = 1;
| label | amount |
|-------|--------|
| bbb | 15 |
| fff | 99 |
但例外结果应为:
| label | amount |
|-------|--------|
| bbb | 15 |
| eee | NULL |
| fff | 99 |
我还尝试了SELECT label UNION ALL label (...) LEFT JOIN
,它应该适用于MySQL(Keep all records in "WHERE IN()" clause, even if they are not found):
SELECT T.label, T.amount FROM (
SELECT 'bbb' AS "lbl"
UNION ALL 'eee' AS "lbl"
UNION ALL 'fff' AS "lbl"
) LABELS
LEFT OUTER JOIN table T ON (LABELS."lbl" = T."label")
WHERE T.fkey = 1;
以及WITH
声明:
WITH LABELS AS (
SELECT 'bbb' AS "lbl"
UNION ALL 'eee' AS "lbl"
UNION ALL 'fff' AS "lbl"
)
SELECT T.label, T.amount FROM LABELS
LEFT OUTER JOIN table T ON (LABELS."lbl" = T."label")
WHERE T.fkey = 1;
但总是这个LEFT JOIN
给我2行istead 3.
创建临时表根本不起作用(我从中得到0行,我不能在连接中使用它):
CREATE TEMPORARY TABLE __ids (
id VARCHAR(9) PRIMARY KEY
) ON COMMIT DELETE ROWS;
INSERT INTO __ids (id) VALUES
('bbb'),
('eee'),
('fff');
SELECT
*
FROM __ids
知道如何强制Postgres保持空关系吗?或者甚至是任何其他想法来获得标签' eee'如果表中没有这个行,那么是否为NULL?
每个请求的标签列表都可以不同。
此案例在线:http://rextester.com/CRQY46630
------编辑-----
我用过滤器where
扩展了这个问题,因为来自a_horse_with_no_name的回答非常好,但不能涵盖我的整个案例(无论如何我都认为这个where
)
答案 0 :(得分:3)
您使用外部联接的方法有效。您只需要从"外部"中获取标签值。加入表格,而不是来自"表格":
with labels (lbl) as (
values ('bbb'), ('eee'), ('fff')
)
select l.lbl, --<< this is different to your query
t.amount
from labels l
left outer join "table" t on l.lbl = t.label;
在线示例:http://rextester.com/LESK82163
问题范围扩大后,编辑。
如果要在基表上进行过滤,则需要移入JOIN
条件,而不是where子句:
with labels (lbl) as (
values ('bbb'), ('eee'), ('fff')
)
select l.lbl, --<< this is different to your query
t.amount
from labels l
left outer join "table" t
on l.lbl = t.label
and t.fkey = 1; --<<