oracle 表自连接

b1uwtaje  于 2023-04-29  发布在  Oracle
关注(0)|答案(3)|浏览(119)

我有一个table_1看起来像这样:
| 通用ID|类型|人员_ID|
| --------------|--------------|--------------|
| 一百二十三|0|七十八|
| 一百二十三|二|八九|
| 一百二十三|二|六十三|
| 一百二十三|二|二十六|
| 四五六|0|九九|
| 四五六|二|十三|
因此,人员78与人员89、63、26相关,因为他们共享相同的Common_ID 123。人78具有类型0,这意味着他是主要联系人。人89、63、26具有类型2,因此他们是次要接触。
我想创建一个新表,如下所示:
| 小学|其他1|其他2|其他3|
| --------------|--------------|--------------|--------------|
| 七十八|八九|六十三|二十六|
| 九九|十三|零|零|
我想我需要自连接此表。我这样写:

select T1.person_ID,T2.person_ID, T3.person_ID, T4.person_ID,  
from table_1 T1
left outer join table_1 T2 on T1.Common_ID=T2.Common_ID
left outer join table_1 T3 on T1.Common_ID=T3.Common_ID
left outer join table_1 T4 on T1.Common_ID=T4.Common_ID
where T1.type=0
and T2.type=2
and T3.type=2
and T4.type=2
and T1.person_ID <> T2.person_ID
and T1.person_ID <> T3.person_ID
and T1.person_ID <> T4.person_ID
and T2.person_ID <> T3.person_ID
and T2.person_ID <> T4.person_ID
and T3.person_ID <> T4.person_ID

我添加了像和T1这样的过滤器。person_ID〈〉T2。person_ID是因为我不希望同一个Secondary person出现多次。
但是上面的代码没有返回想要的结果。因为像和T1这样的过滤器。person_ID〈〉T2。person_ID,person 99和13不会被返回,我认为这是由于Oracle无法比较NULL?
我要所有人都回来包括99号和13号。你能帮帮忙吗?非常感谢!

dgiusagp

dgiusagp1#

您可以将子句添加到连接中,这样就不会从完整查询中排除空值

select T1.person_ID,T2.person_ID, T3.person_ID, T4.person_ID,  
from table_1 T1
left outer join table_1 T2 on T1.Common_ID=T2.Common_ID 
and T1.person_ID <> T2.person_ID
left outer join table_1 T3 on T1.Common_ID=T3.Common_ID
and T1.person_ID <> T3.person_ID
and T2.person_ID <> T3.person_ID
left outer join table_1 T4 on T1.Common_ID=T4.Common_ID
and T1.person_ID <> T4.person_ID
and T2.person_ID <> T4.person_ID
and T3.person_ID <> T4.person_ID
where T1.type=0
and T2.type=2
and T3.type=2
and T4.type=2
wpx232ag

wpx232ag2#

你可以先使用ROW_NUMBER解析函数,然后再使用PIVOT(并且可以在没有任何自连接的情况下完成):

SELECT *
FROM   (
  SELECT t.*,
         ROW_NUMBER() OVER (PARTITION BY common_id, type ORDER BY person_id) AS rn
  FROM   table_name t
)
PIVOT (
  MAX(person_id)
  FOR (type, rn) IN (
    (0, 1) AS primary,
    (2, 1) AS other1,
    (2, 2) AS other2,
    (2, 3) AS other3
  )
)

其中,对于样本数据:

CREATE TABLE table_name (Common_ID, Type, Person_ID) AS
SELECT 123, 0, 78 FROM DUAL UNION ALL
SELECT 123, 2, 89 FROM DUAL UNION ALL
SELECT 123, 2, 63 FROM DUAL UNION ALL
SELECT 123, 2, 26 FROM DUAL UNION ALL
SELECT 456, 0, 99 FROM DUAL UNION ALL
SELECT 456, 2, 13 FROM DUAL;

输出:
| 通用ID|初级|其他1|其他2|其他3|
| --------------|--------------|--------------|--------------|--------------|
| 一百二十三|七十八|二十六|六十三|八九|
| 四五六|九九|十三|联系我们|联系我们|
fiddle

mqkwyuun

mqkwyuun3#

其中一个选项是连接来自同一个表的两个查询:

WITH        --  Sample data 
    tbl (COMMON_ID, A_TYPE, PERSON_ID) AS
        (   
            Select 123, 0, 78 From Dual Union All
            Select 123, 2, 89 From Dual Union All
            Select 123, 2, 63 From Dual Union All
            Select 123, 2, 26 From Dual Union All
            Select 456, 0, 99 From Dual Union All
            Select 456, 2, 13 From Dual 
        )

主SQL

SELECT  t.PRIMARY, 
        Max(CASE RN WHEN 1 THEN PERSON_ID END) "OTHER_1",
        Max(CASE RN WHEN 2 THEN PERSON_ID END) "OTHER_2",
        Max(CASE RN WHEN 3 THEN PERSON_ID END) "OTHER_3"
FROM    ( Select  COMMON_ID, 
                  Max(CASE WHEN A_TYPE = 0 THEN PERSON_ID END) "PRIMARY"
          From    tbl
          Group By COMMON_ID
          Order By COMMON_ID  ) t
INNER JOIN  ( Select  ROW_NUMBER() OVER(Partition By COMMON_ID Order By PERSON_ID DESC) "RN", 
                      COMMON_ID, PERSON_ID
              From    tbl
              Where   A_TYPE = 2
            ) t2 ON(t2.COMMON_ID = t.COMMON_ID)
GROUP BY t.PRIMARY

回复:
| 初级|其他_1|其他_2|其他3|
| --------------|--------------|--------------|--------------|
| 七十八|八九|六十三|二十六|
| 九九|十三|空|空|
注意:如果有超过3个其他人的id,你也应该处理,要么把它们作为一个列表放在一列中,要么像这个答案一样。我命令其他人把最新的人的ID放在第一位,就像你预期的结果一样。

相关问题