Postgresql 在具有限制的联接表中获取空值
我从中学到了很多类似的问题,但我的结果集并没有返回预期的结果 我的目标:Postgresql 在具有限制的联接表中获取空值,postgresql,join,Postgresql,Join,我从中学到了很多类似的问题,但我的结果集并没有返回预期的结果 我的目标: id user_id product quantity warehouse 1 admin phone 3 A 2 admin desk 1 D 3 k45 chair 5 B id user_id employee job country 1 admin james tech u
id user_id product quantity warehouse
1 admin phone 3 A
2 admin desk 1 D
3 k45 chair 5 B
id user_id employee job country
1 admin james tech usa
2 c39 cindy tech spain
SELECT *
from demo1
left join (SELECT * FROM demo2 WHERE demo2.user_id = 'X' LIMIT 1) X
on (demo1.user_id = x.user_id)
WHERE demo1.user_id = 'admin'
id user_id product quantity warehouse id employee job country
1 admin phone 3 A null null null null
2 admin desk 1 D null null null null
id user_id product quantity warehouse id employee job country
1 admin phone 3 A 1 james tech usa
2 admin desk 1 D null null null null
构建一个查询,该查询将返回一个结果集,其中包含用户id为“admin”的表demo1
中的所有行,以及用户id为“admin”的表demo2
中唯一一行。demo2
中的每一行都有一个唯一的user\u id
,因此始终只有一行的“admin”作为user\u id
但是,我不希望demo2
数据在demo1
的后续每一行上重复浪费。我只希望结果集的第一行包含作为非空值的demo2
数据。只应为结果集中的第2行+返回demo2
列的空值
当前状态:
id user_id product quantity warehouse
1 admin phone 3 A
2 admin desk 1 D
3 k45 chair 5 B
id user_id employee job country
1 admin james tech usa
2 c39 cindy tech spain
SELECT *
from demo1
left join (SELECT * FROM demo2 WHERE demo2.user_id = 'X' LIMIT 1) X
on (demo1.user_id = x.user_id)
WHERE demo1.user_id = 'admin'
id user_id product quantity warehouse id employee job country
1 admin phone 3 A null null null null
2 admin desk 1 D null null null null
id user_id product quantity warehouse id employee job country
1 admin phone 3 A 1 james tech usa
2 admin desk 1 D null null null null
现在,我的查询正在返回相应的列(所有demo1
和所有demo2
),但是
从demo2
返回的所有数据都是null
Demo1:
id user_id product quantity warehouse
1 admin phone 3 A
2 admin desk 1 D
3 k45 chair 5 B
id user_id employee job country
1 admin james tech usa
2 c39 cindy tech spain
SELECT *
from demo1
left join (SELECT * FROM demo2 WHERE demo2.user_id = 'X' LIMIT 1) X
on (demo1.user_id = x.user_id)
WHERE demo1.user_id = 'admin'
id user_id product quantity warehouse id employee job country
1 admin phone 3 A null null null null
2 admin desk 1 D null null null null
id user_id product quantity warehouse id employee job country
1 admin phone 3 A 1 james tech usa
2 admin desk 1 D null null null null
演示2:
id user_id product quantity warehouse
1 admin phone 3 A
2 admin desk 1 D
3 k45 chair 5 B
id user_id employee job country
1 admin james tech usa
2 c39 cindy tech spain
SELECT *
from demo1
left join (SELECT * FROM demo2 WHERE demo2.user_id = 'X' LIMIT 1) X
on (demo1.user_id = x.user_id)
WHERE demo1.user_id = 'admin'
id user_id product quantity warehouse id employee job country
1 admin phone 3 A null null null null
2 admin desk 1 D null null null null
id user_id product quantity warehouse id employee job country
1 admin phone 3 A 1 james tech usa
2 admin desk 1 D null null null null
查询:
id user_id product quantity warehouse
1 admin phone 3 A
2 admin desk 1 D
3 k45 chair 5 B
id user_id employee job country
1 admin james tech usa
2 c39 cindy tech spain
SELECT *
from demo1
left join (SELECT * FROM demo2 WHERE demo2.user_id = 'X' LIMIT 1) X
on (demo1.user_id = x.user_id)
WHERE demo1.user_id = 'admin'
id user_id product quantity warehouse id employee job country
1 admin phone 3 A null null null null
2 admin desk 1 D null null null null
id user_id product quantity warehouse id employee job country
1 admin phone 3 A 1 james tech usa
2 admin desk 1 D null null null null
理由:
id user_id product quantity warehouse
1 admin phone 3 A
2 admin desk 1 D
3 k45 chair 5 B
id user_id employee job country
1 admin james tech usa
2 c39 cindy tech spain
SELECT *
from demo1
left join (SELECT * FROM demo2 WHERE demo2.user_id = 'X' LIMIT 1) X
on (demo1.user_id = x.user_id)
WHERE demo1.user_id = 'admin'
id user_id product quantity warehouse id employee job country
1 admin phone 3 A null null null null
2 admin desk 1 D null null null null
id user_id product quantity warehouse id employee job country
1 admin phone 3 A 1 james tech usa
2 admin desk 1 D null null null null
子查询的LIMIT 1
是我试图仅检索第1行的demo2
值,认为其余的将是null
。相反,所有值都是null
当前结果:
id user_id product quantity warehouse
1 admin phone 3 A
2 admin desk 1 D
3 k45 chair 5 B
id user_id employee job country
1 admin james tech usa
2 c39 cindy tech spain
SELECT *
from demo1
left join (SELECT * FROM demo2 WHERE demo2.user_id = 'X' LIMIT 1) X
on (demo1.user_id = x.user_id)
WHERE demo1.user_id = 'admin'
id user_id product quantity warehouse id employee job country
1 admin phone 3 A null null null null
2 admin desk 1 D null null null null
id user_id product quantity warehouse id employee job country
1 admin phone 3 A 1 james tech usa
2 admin desk 1 D null null null null
所需结果:
id user_id product quantity warehouse
1 admin phone 3 A
2 admin desk 1 D
3 k45 chair 5 B
id user_id employee job country
1 admin james tech usa
2 c39 cindy tech spain
SELECT *
from demo1
left join (SELECT * FROM demo2 WHERE demo2.user_id = 'X' LIMIT 1) X
on (demo1.user_id = x.user_id)
WHERE demo1.user_id = 'admin'
id user_id product quantity warehouse id employee job country
1 admin phone 3 A null null null null
2 admin desk 1 D null null null null
id user_id product quantity warehouse id employee job country
1 admin phone 3 A 1 james tech usa
2 admin desk 1 D null null null null
我尝试用
左连接
替换左内部连接
,右连接
,完全连接
,但没有返回所需的结果。您的连接将带来满足两个表的连接条件的所有记录。这是无法改变的
但是,您可以禁止结果集中的后续记录在加入后显示满足加入条件的匹配demo2
记录:
SELECT demo1.id ,
demo1.user_id,
demo1.product,
demo1.quantity,
demo1.warehouse
CASE WHEN ROW_NUMBER() OVER (PARTITION BY demo1.user_id ORDER BY demo1.id) = 1 THEN demo2.id END as demo2_id,
CASE WHEN ROW_NUMBER() OVER (PARTITION BY demo1.user_id ORDER BY demo1.id) = 1 THEN demo2.employee END AS demo2_employee,
CASE WHEN ROW_NUMBER() OVER (PARTITION BY demo1.user_id ORDER BY demo1.id) = 1 THEN demo2.job END as demo2_job,
CASE WHEN ROW_NUMBER() OVER (PARTITION BY demo1.user_id ORDER BY demo1.id) = 1 THEN demo2.country END as demo2_country
from demo1
left join demo2
on demo1.user_id = demo2.user_id
AND demo2.user_id = 'X'
WHERE demo1.user_id = 'admin'
这只是对原始sql的快速重写,添加了CASE
表达式
也就是说,此sql不会为demo2
生成任何结果,因为demo2.user\u id
不能同时满足此查询中的两个条件:
demo1.user\u id=demo2.user\u id
与demo1.user\u id='admin'的where谓词
X
它要么是
admin
,满足您的第一个加入条件,但第二个加入条件失败。或者它是X
,满足您的第二个条件,但也不是第一个条件。您的联接将为两个表带来满足联接条件的任何记录。这是无法改变的
但是,您可以禁止结果集中的后续记录在加入后显示满足加入条件的匹配demo2
记录:
SELECT demo1.id ,
demo1.user_id,
demo1.product,
demo1.quantity,
demo1.warehouse
CASE WHEN ROW_NUMBER() OVER (PARTITION BY demo1.user_id ORDER BY demo1.id) = 1 THEN demo2.id END as demo2_id,
CASE WHEN ROW_NUMBER() OVER (PARTITION BY demo1.user_id ORDER BY demo1.id) = 1 THEN demo2.employee END AS demo2_employee,
CASE WHEN ROW_NUMBER() OVER (PARTITION BY demo1.user_id ORDER BY demo1.id) = 1 THEN demo2.job END as demo2_job,
CASE WHEN ROW_NUMBER() OVER (PARTITION BY demo1.user_id ORDER BY demo1.id) = 1 THEN demo2.country END as demo2_country
from demo1
left join demo2
on demo1.user_id = demo2.user_id
AND demo2.user_id = 'X'
WHERE demo1.user_id = 'admin'
这只是对原始sql的快速重写,添加了CASE
表达式
也就是说,此sql不会为demo2
生成任何结果,因为demo2.user\u id
不能同时满足此查询中的两个条件:
demo1.user\u id=demo2.user\u id
与demo1.user\u id='admin'的where谓词
X
它要么是
admin
,满足您的第一个加入条件,但第二个加入条件失败。或者它是X
,满足第二个条件,但也不满足第一个条件。这里是另一个不错的方法:
这里是另一个不错的方法:
谢谢,但是
CASE
语句缺少一个括号,因此我无法运行查询。我在想办法。请编辑,如果你在这里哦,我的天。是的,我真的搞砸了。等一下,好的。修正了那个打字错误。基本上,这就是创建一个结果集记录的“窗口”,其中每个不同的demo1.user\u id
定义了一个不同的窗口。然后在该窗口中,我们按demo1.id
排序,并应用行编号()。如果是该窗口中的行1
,那么我们允许Demo2
结果在该记录中通过。完美。这就是我在下面一两段中所说的。为了好玩,请取出和demo2.user\u id='X'
并重新运行。这里的性能影响是:1)您的where谓词位于user\u id
上。如果该字段被索引,那么性能将得到改善。2) 把两张桌子连接起来。显然,这需要付出代价。索引会有所帮助,但联接就是联接,它就像数据库的整个点。3) 窗口可以正常工作。没有索引会将您保存在这里,因此您唯一的选择是只处理demo2
字段中包含数据的每一行,因此它就是这样。不过,我很高兴我们能成功!:)谢谢,但是CASE
语句缺少一个括号,因此我无法运行查询。我在想办法。请编辑,如果你在这里哦,我的天。是的,我真的搞砸了。等一下,好的。修正了那个打字错误。基本上,这就是创建一个结果集记录的“窗口”,其中每个不同的demo1.user\u id
定义了一个不同的窗口。然后在该窗口中,我们按demo1.id
排序,并应用行编号()。如果是该窗口中的行1
,那么我们允许Demo2
结果在该记录中通过。完美。这就是我在下面一两段中所说的。为了好玩,请取出和demo2.user\u id='X'
并重新运行。这里的性能影响是:1)您的where谓词位于user\u id
上。如果该字段被索引,那么性能将得到改善。2) 把两张桌子连接起来。显然,这需要付出代价。索引会有所帮助,但联接就是联接,它就像数据库的整个点。3) 窗口可以正常工作。没有索引会把你保存在这里,所以你唯一的选择就是交易