我正在尝试确认一个向document_id
发送direction flag = 'O'
并接收相同document_id
的流程并将其记录在同一个表中,但是在新行中并且不同专栏:src_document_id
,direction = 'I
'。
需要识别已发送的记录(方向标志= O),这些记录没有src_document_id
direction_flag = 'I'
的匹配值。当我根据入站值检查出站值时,不确定我是否使用EXISTS或Not Exists。
下表中的EX:查询应该返回Document_id 34567,因为它没有带Direction_flag = I的相应src_document_id。
select
document_id
from
DOCUMENT_TABLE
where
direction_flag = 'O'
and
client_id = '9999'
and
EXISTS
(
select
document_id
from
DOCUMENT_TABLE
where
document_id != src_document_id and direction_flag = 'I'
)
希望我足够清楚。不熟悉SQL。
DOCUMENT_ TABLE:
Document_id client number Direction flag src_document_id
12345 9999 O
23456 9999 O
34567 9999 O
aaaaa I 12345
aaaab I 23456
答案 0 :(得分:0)
您可以使用左连接在id字段上将表连接到自身。这将显示左侧的所有记录,仅显示匹配的右侧记录。在where子句中,您可以过滤掉不匹配的记录(src_document_id为null)。
SELECT
d1.document_id
FROM DOCUMENT_TABLE d1
LEFT JOIN DOCUMENT_TABLE d2 ON d1.document_id = d2.src_document_id
WHERE
d1.direction_flag = 'O' AND
d2.src_document_id IS NULL AND
d2.direction_flag = 'I'
答案 1 :(得分:0)
相关子查询通常性能较差。我认为您的查询会更好地使用自连接子查询。
(相关的子查询一般来说是存在于SELECT
子句或WHERE
子句中的子查询,并且对集合中的每一行进行求值,这自然是低效的(想想:{{1复杂性)并且总是不会产生优化的执行计划。)
我会这样:
O(n*m)
注意我对子查询使用完整查询,因为它为源文档" SELECT
[source].document_id
FROM
(
SELECT
document_id
FROM
document_table
WHERE
direction_flag = 'O'
) AS [source]
LEFT JOIN
(
SELECT
document_id,
src_document_id
FROM
document_table
WHERE
direction_flag = 'I'
) AS [dest]
ON [source].document_id = [dest].src_document_id
WHERE
dest.document_id IS NULL
之间的意图和区别做出了贡献。和" document_table
用于目的地文件"与诸如@Donal gave in his answer之类的更紧凑的查询相比更加清晰 - 它完全取决于样式和可读性,因为两个查询都是正确的。
答案 2 :(得分:0)
Dai's answer是正确的
但Donal's answer有一点错误。对于正确的答案,它应该是这样的:
SELECT
d1.document_id
FROM DOCUMENT_TABLE d1
LEFT JOIN DOCUMENT_TABLE d2 ON d1.document_id = d2.src_document_id
AND d2.direction_flag = 'I'
WHERE
d1.direction_flag = 'O' AND
d2.src_document_id IS NULL
自" d2.src_document_id"语句"总是为空d2.direction_flag ='我' "在哪里条件无用。