内部连接相同的查询 returns 比单独执行时多结果
Inner joined same query returns more result than when it's executed alone
我不知道我是否错了,但我一直认为(现在仍然如此)记录的数量 return 是通过单独查询 table 和内部连接得到的相同的 table 和查询此关系将是相同的。像这样:
select 'foo' foo from dual;
对比
select * from (select 'foo' foo from dual)q1 inner join
(select 'foo' foo from dual)q2
on q1.foo=q2.foo
这两个查询 return 一条记录。但是我有一个查询,当我在内部将它与自身连接时,我得到了更多的记录。这是我的查询:
SELECT distinct DOC.DOCID
FROM AG_INW_DOC DOC
JOIN LAG_CITIZENS CIT
ON DOC.CITIZENID=CIT.CITIZENID
JOIN
(SELECT TSK.DOCID,
OFCR.DEPID
FROM AG_TASKS TSK
JOIN AG_TASK_EXECUTORS EXEC
ON TSK.TASKID=EXEC.TASKID
JOIN AG_OFFICERS OFCR
ON EXEC.ISSUEDOFFICERID =OFCR.OFFICERID
WHERE EXEC.ISMAINEXECUTOR =1
)TSK ON DOC.DOCID =TSK.DOCID
LEFT JOIN
(SELECT ESCDOCID, UNDERCONTROL,ORGID FROM AG_ESCORTING_DOCUMENTS
) ESC
ON DOC.ESCDOCID =ESC.ESCDOCID
WHERE DOC.CATEGORYID IN (11,12)
AND TRUNC(DOC.RECEIVEDDATE,'DDD') BETWEEN TO_DATE('01.11.2015') AND TO_DATE('30.11.2015')
AND (TSK.DEPID IN ('017','004')
OR (TSK.DEPID ='008'
AND DOC.SUBJECTID IN (1,2,3,4,20,22,23,24) ))
AND DOC.DOCSTAT! =3
UNION ALL
SELECT distinct DOC.DOCID
FROM AG_INW_DOC DOC
JOIN LAG_CITIZENS CIT
ON DOC.CITIZENID=CIT.CITIZENID
LEFT JOIN AG_TASKS TSK
ON DOC.DOCID =TSK.DOCID
LEFT JOIN
(SELECT ESCDOCID, UNDERCONTROL,ORGID FROM AG_ESCORTING_DOCUMENTS
) ESC
ON DOC.ESCDOCID =ESC.ESCDOCID
WHERE DOC.CATEGORYID IN (11,12)
AND DOC.ADDRESSEDOFFICERID IN (9,26)
AND TRUNC(DOC.RECEIVEDDATE,'DDD') BETWEEN TO_DATE('01.11.2015') AND TO_DATE('30.11.2015')
AND DOC.DOCSTAT! =3
如果我单独 运行 这个查询,我会得到 3019 条记录 returned。但是如果我 inner join
它本身和 select 从这个连接我得到 3023 条记录。
现在,我不希望有人检查我的查询并指出问题所在。我只需要知道什么情况可能会导致这种行为。
编辑
查询 return 只有不同的值。无重复
你的假设是错误的。
内部联接会将第一个 select 的每个结果与第二个 select 的每个结果组合起来,然后过滤联接条件。因此,如果您的 select returns 具有以下三个值的单个列:
1, 2, 2
与自身的连接以及值必须相同的连接条件将产生
所以你得到 5 行而不是 3 行。
如果不查看您的实际 select,您的连接条件的列中可能有非唯一值。
(1, 1), (2, 2), (2, 2), (2, 2), (2, 2)
为了找到重复项,您可以像这样完成查询
select DOCID, count(*) from (
-- your query here
) group by DOCID
having count(*) > 1
仅当您加入主键或唯一键时,您的假设才成立。
这里有一个小例子来说明相反的情况:
此查询给出了两行,但键不是唯一的:
select 'foo, I''M no PK' foo from dual union all
select 'foo, I''M no PK' foo from dual
;
连接上面的行源(使用 WITH)给出 2 * 2 行。
with dual2 as (
select 'foo, I''M no PK' foo from dual union all
select 'foo, I''M no PK' foo from dual
)
select * from (select foo from dual2)q1 inner join
(select foo from dual2)q2
on q1.foo=q2.foo
;
.
foo, I'M no PK foo, I'M no PK
foo, I'M no PK foo, I'M no PK
foo, I'M no PK foo, I'M no PK
foo, I'M no PK foo, I'M no PK
更新
以上假设成立,但与本题无关。
问题出在构造上DISTINCT UNION ALL DISTINCT
这可能会出现错误 - 必须改用 UNION
。
例子
with tab1 as (
select 1 foo from dual union all
select 1 foo from dual union all
select 2 foo from dual)
, tab2 as (
select 2 foo from dual union all
select 2 foo from dual union all
select 3 foo from dual)
select DISTINCT foo from tab1
UNION ALL
select DISTINCT foo from tab2
order by 1;
给予
1
2
2
3
我不知道我是否错了,但我一直认为(现在仍然如此)记录的数量 return 是通过单独查询 table 和内部连接得到的相同的 table 和查询此关系将是相同的。像这样:
select 'foo' foo from dual;
对比
select * from (select 'foo' foo from dual)q1 inner join
(select 'foo' foo from dual)q2
on q1.foo=q2.foo
这两个查询 return 一条记录。但是我有一个查询,当我在内部将它与自身连接时,我得到了更多的记录。这是我的查询:
SELECT distinct DOC.DOCID
FROM AG_INW_DOC DOC
JOIN LAG_CITIZENS CIT
ON DOC.CITIZENID=CIT.CITIZENID
JOIN
(SELECT TSK.DOCID,
OFCR.DEPID
FROM AG_TASKS TSK
JOIN AG_TASK_EXECUTORS EXEC
ON TSK.TASKID=EXEC.TASKID
JOIN AG_OFFICERS OFCR
ON EXEC.ISSUEDOFFICERID =OFCR.OFFICERID
WHERE EXEC.ISMAINEXECUTOR =1
)TSK ON DOC.DOCID =TSK.DOCID
LEFT JOIN
(SELECT ESCDOCID, UNDERCONTROL,ORGID FROM AG_ESCORTING_DOCUMENTS
) ESC
ON DOC.ESCDOCID =ESC.ESCDOCID
WHERE DOC.CATEGORYID IN (11,12)
AND TRUNC(DOC.RECEIVEDDATE,'DDD') BETWEEN TO_DATE('01.11.2015') AND TO_DATE('30.11.2015')
AND (TSK.DEPID IN ('017','004')
OR (TSK.DEPID ='008'
AND DOC.SUBJECTID IN (1,2,3,4,20,22,23,24) ))
AND DOC.DOCSTAT! =3
UNION ALL
SELECT distinct DOC.DOCID
FROM AG_INW_DOC DOC
JOIN LAG_CITIZENS CIT
ON DOC.CITIZENID=CIT.CITIZENID
LEFT JOIN AG_TASKS TSK
ON DOC.DOCID =TSK.DOCID
LEFT JOIN
(SELECT ESCDOCID, UNDERCONTROL,ORGID FROM AG_ESCORTING_DOCUMENTS
) ESC
ON DOC.ESCDOCID =ESC.ESCDOCID
WHERE DOC.CATEGORYID IN (11,12)
AND DOC.ADDRESSEDOFFICERID IN (9,26)
AND TRUNC(DOC.RECEIVEDDATE,'DDD') BETWEEN TO_DATE('01.11.2015') AND TO_DATE('30.11.2015')
AND DOC.DOCSTAT! =3
如果我单独 运行 这个查询,我会得到 3019 条记录 returned。但是如果我 inner join
它本身和 select 从这个连接我得到 3023 条记录。
现在,我不希望有人检查我的查询并指出问题所在。我只需要知道什么情况可能会导致这种行为。
编辑
查询 return 只有不同的值。无重复
你的假设是错误的。
内部联接会将第一个 select 的每个结果与第二个 select 的每个结果组合起来,然后过滤联接条件。因此,如果您的 select returns 具有以下三个值的单个列:
1, 2, 2
与自身的连接以及值必须相同的连接条件将产生
所以你得到 5 行而不是 3 行。
如果不查看您的实际 select,您的连接条件的列中可能有非唯一值。
(1, 1), (2, 2), (2, 2), (2, 2), (2, 2)
为了找到重复项,您可以像这样完成查询
select DOCID, count(*) from (
-- your query here
) group by DOCID
having count(*) > 1
仅当您加入主键或唯一键时,您的假设才成立。
这里有一个小例子来说明相反的情况:
此查询给出了两行,但键不是唯一的:
select 'foo, I''M no PK' foo from dual union all
select 'foo, I''M no PK' foo from dual
;
连接上面的行源(使用 WITH)给出 2 * 2 行。
with dual2 as (
select 'foo, I''M no PK' foo from dual union all
select 'foo, I''M no PK' foo from dual
)
select * from (select foo from dual2)q1 inner join
(select foo from dual2)q2
on q1.foo=q2.foo
;
.
foo, I'M no PK foo, I'M no PK
foo, I'M no PK foo, I'M no PK
foo, I'M no PK foo, I'M no PK
foo, I'M no PK foo, I'M no PK
更新
以上假设成立,但与本题无关。
问题出在构造上DISTINCT UNION ALL DISTINCT
这可能会出现错误 - 必须改用 UNION
。
例子
with tab1 as (
select 1 foo from dual union all
select 1 foo from dual union all
select 2 foo from dual)
, tab2 as (
select 2 foo from dual union all
select 2 foo from dual union all
select 3 foo from dual)
select DISTINCT foo from tab1
UNION ALL
select DISTINCT foo from tab2
order by 1;
给予
1
2
2
3