内部联接三个表似乎是错误的

时间:2018-11-28 16:41:10

标签: sql postgresql join

我想内部连接三个有条件的表。
一个条件是DAT.STATE_ID IN('7','8','9')。
计数为116,带有以下查询。

select count(*) from "B_TRACE"."P_TC_DATA" DAT WHERE DAT."STATE_ID" IN ('7','8','9');

但是,随着下面的查询联接三个表,计数增加到146。 计数应该小于116。这似乎不正确。
内部联接查询出了什么问题?

SELECT DAT.*, SUBID.*, TR.* 
FROM "B_TRACE"."P_TC_DATA" AS DAT, 
    "B_CC"."CC_CONSENT_RECORD" AS SUBID, 
    "B_TRACE"."P_TC_RECORD" AS TR
WHERE TR."P_SERIAL_ID" = SUBID."SUBJECT_ID" 
    AND TR."P_SERIAL_ID" = DAT."P_SERIAL_ID" 
    AND  (DAT."STATE_ID" IN ('7','8','9')) 
    AND (SUBID."SUBJECT_C_ID" IS NOT NULL)

另一种尝试,仍然有146行

SELECT DATS.*, SUBID.*, TR.* 
FROM (select * from "B_TRACE"."P_TC_DATA" DAT WHERE DAT."STATE_ID" IN ('7','8','9')) AS DATS, 
    "B_CC"."CC_CONSENT_RECORD" AS SUBID, 
    "B_TRACE"."P_TC_RECORD" AS TR
WHERE TR."P_SERIAL_ID" = SUBID."SUBJECT_ID" 
    AND TR."P_SERIAL_ID" = DATS."P_SERIAL_ID"  
    AND (SUBID."SUBJECT_C_ID" IS NOT NULL)

一些尝试

--got 379 rows
SELECT  SUBID.*, TR.* 
FROM  
    "B_CC"."CC_CONSENT_RECORD" AS SUBID, 
    "B_TRACE"."P_TC_RECORD" AS TR
WHERE TR."P_SERIAL_ID" = SUBID."SUBJECT_ID" 


--got 91 rows
SELECT DATS.*, SUBID.* 
FROM (SELECT * FROM "B_TRACE"."P_TC_DATA" DAT WHERE DAT."STATE_ID" IN ('7','8','9')) AS DATS, 
    "B_CC"."CC_CONSENT_RECORD" AS SUBID,    
WHERE SUBID."SUBJECT_ID"=DATS."P_SERIAL_ID" 


--got 181 rows  
SELECT DATS.*, TR.* 
FROM (SELECT * FROM "B_TRACE"."P_TC_DATA" DAT WHERE DAT."STATE_ID" IN ('7','8','9')) AS DATS,  
    "B_TRACE"."P_TC_RECORD" AS TR
WHERE TR."P_SERIAL_ID" = DATS."P_SERIAL_ID"

2 个答案:

答案 0 :(得分:0)

请尝试在以下显式联接下进行尝试

    SELECT DAT.*, SUBID.*, TR.* 
    FROM "B_TRACE"."P_TC_RECORD" AS TR join
    "B_CC"."CC_CONSENT_RECORD" AS SUBID on TR."P_SERIAL_ID" = SUBID."SUBJECT_ID"
    join "B_TRACE"."P_TC_DATA" AS DAT on TR."P_SERIAL_ID" = DAT."P_SERIAL_ID"
     where
     AND  DAT."STATE_ID" IN ('7','8','9')
     AND SUBID."SUBJECT_C_ID" IS NOT NULL

答案 1 :(得分:0)

CC_CONSENT_RECORD中可能有重复的SUBJECT_ID。因此,对于每个重复项,在加入P_TC_DATA时都会增加计数。

您可以对此进行测试

SELECT CONS.SUBJECT_ID, COUNT(*)
FROM B_TRACE.P_TC_DATA AS DATA
JOIN B_CC.CC_CONSENT_RECORD AS CONS 
  ON CONS.SUBJECT_ID = DATA.P_SERIAL_ID
WHERE DATA.STATE_ID IN ('7', '8', '9')
GROUP BY CONS.SUBJECT_ID
HAVING COUNT(*) > 1

这是查询的替代方法

SELECT DATA.*, CONS.*, REC.* 
FROM B_TRACE.P_TC_DATA AS DATA
JOIN B_CC.CC_CONSENT_RECORD AS CONS 
  ON (CONS.SUBJECT_ID = DATA.P_SERIAL_ID AND CONS.SUBJECT_C_ID IS NOT NULL)
LEFT JOIN B_TRACE.P_TC_RECORD AS REC 
  ON REC.P_SERIAL_ID = DATA.P_SERIAL_ID
WHERE DATA.STATE_ID IN ('7', '8', '9')