我从中学到了许多类似的问题,但我的结果集并没有返回预期的结果。
我的目标:
构建一个查询,该查询将返回包含demo1
=“admin”表user_id
中所有行的结果集,以及demo2
=“admin”表user_id
的唯一行。 demo2
中的每一行都有一个独特的user_id
,所以总有一行“admin”作为user_id
。
但是,我不希望demo2
数据浪费地重复在demo1
的每一行。我只希望结果集的第一行包含demo2
数据作为非空值。 demo2
列的空值只应返回结果集中的行2+。
当前状态:
现在我的查询返回适当的列(所有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
DEMO2:
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'
理由:
子查询的LIMIT 1
是我试图仅检索第1行的demo2
值,认为其余的将是null
。相反,所有值都是null
。
目前的结果:
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
我已经尝试用left join
代替left inner join
,right join
,full join
,但没有任何东西可以返回所需的结果。
您的联接将带来满足两个表的连接条件的任何记录。没有改变。
但是,您可以通过显示匹配的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_id
不能满足此查询中的两个条件:
demo1.user_id = demo2.user_id
与demo1.user_id = 'admin'
的where谓词X
。它是admin
并且满足你的第一次加入条件,但是你的第二次失败。或者它是X
并满足你的第二个条件,但也不是你的第一个条件。
这是另一个不错的方法:sqlfiddle