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) 窗口可以正常工作。没有索引会把你保存在这里,所以你唯一的选择就是交易