为什么合并返回标量子查询返回多行,即使值不同 - SQL

问题描述 投票:0回答:1

我有 2 张桌子想要加入。这些表是

kp.pi
g.gu

kp.pi
与基于
g.gu
pi.xx_id = gu.yy_id
pi.xx_type = gu.yy_type
联接,我想在此联接之后从
userid
表中获取
g.gu
字段。

但是,在某些情况下,由于两个表中的类型(即 pi.xx_type = gu.yy_type)不匹配,因此会为

userid
返回 null。因此,如果类型不匹配,我想排除此连接条件以从
userid
获取
g.gu

因此查询将是相同的,只是排除

pi.xx_type = gu.yy_type
连接条件以从
g.gu
获取用户 ID。

我尝试使用合并来做到这一点,但不知何故不断收到错误:

Scalar sub-query has returned multiple rows
即使
userid
值在
g.gu
表中不同。

有人能看出我下面的查询有什么问题吗?:

  select submission_id, xx_id, coalesce (userid ,
                  (select distinct userid from 
                 ( SELECT *
                 from kp.pi
                 where source like '%abc%'
                 and id in (123,
                 456,
                 7877
                 )
                 ) pi

                  left join

                  (select  yy_id,
                        id as userid,
                         case
                         when type = 1 then 'bb'
                         when type = 2 then 'cc'
                         when type = 3 then 'dd' end as yy_type
                 from g.gu)
                 on xx_id = yy_id
                 )
                 )
                  as test_userid              
                 from
                 (select
                 id as submission_id,
                 xx_id,
                 xx_type
                 from kp.pi
                 where source like '%abc%'
                 and id in (123,
                 456,
                 7877
                 )
                 ) pi

                 left join

                 (select yy_id,
                  id as userid,
                  case
                         when type = 1 then 'bb'
                         when type = 2 then 'cc'
                         when type = 3 then 'dd' end as yy_type
                 from g.gu   
                 ) gu
                 on pi.xx_id = gu.yy_id
                and pi.xx_type = gu.yy_type
sql subquery coalesce trino
1个回答
0
投票

在没有代表性数据样本的情况下,需要对数据做出假设。我相信您正在尝试优先考虑具有匹配

pi.xx_type = gu.yy_type
的用户 ID,但如果无法使用不满足该条件的用户 ID。我建议不要尝试将此逻辑放入连接中,而是使用
row_number() over(partition by id order by case when type in (1,2,3) then 1 else 2 end)
这将为每个
gu.id
提供 1 的行号,并且由于使用的排序,该行号将属于类型 1,2,3如果可用,否则转到下一个可用类型。然后,通过在连接条件中使用此行号,每个
gu.id
只能获得 1 行,并且该行将按匹配类型/不匹配类型进行优先级排序。

SELECT
      pi.id AS submission_id
    , pi.xx_id
    , gu.userid AS test_userid
FROM kp.pi
LEFT JOIN (
    SELECT
          yy_id
        , id AS userid
        , CASE 
            WHEN type = 1 THEN 'bb'
            WHEN type = 2 THEN 'cc'
            WHEN type = 3 THEN 'dd'
            END AS yy_type
        , row_number() over(partition by id 
                            order by case when type in (1,2,3) then 1 else 2 end) as rn
    FROM g.gu
    ) gu ON pi.xx_id = gu.yy_id AND gu.rn = 1
WHERE pi.source LIKE '%abc%'
    AND pi.id IN (123, 456, 7877)

如果这不能解决问题(例如,您确实希望每个 gu.id 都有类型 aa、bb 和 cc(如果有)),那么请提供每个表中的示例数据以完全代表您的问题。

© www.soinside.com 2019 - 2024. All rights reserved.