SQL - 在同一个表中匹配相同的值,不同的列
Posted
技术标签:
【中文标题】SQL - 在同一个表中匹配相同的值,不同的列【英文标题】:SQL - Matching same value in same table, different columns 【发布时间】:2017-09-18 22:46:11 【问题描述】:我正在尝试确认发送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,因为它没有对应的 src_document_id,Direction_flag = I。
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
【问题讨论】:
【参考方案1】:相关子查询的性能通常很差。我认为您的查询使用自联接子查询会更好。
(相关子查询一般来说是存在于SELECT
子句或WHERE
子句中的子查询,并针对集合中的每一行进行评估,这自然是低效的(想想: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
请注意,我对子查询使用完整查询,因为与 @Donal gave in his answer 等更紧凑的查询相比,它使“document_table
用于源文档”和“document_table
用于目标文档”之间的意图和区别更加清晰- 这完全取决于样式和可读性,因为两个查询都是正确的。
【讨论】:
【参考方案2】:您可以使用左连接在 id 字段上将表连接到自身。这将显示左侧的所有记录,仅显示右侧匹配的记录。在 where 子句中可以过滤掉不匹配的记录(src_document_id 为空)。
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'
【讨论】:
【参考方案3】: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" 始终为 null,因此语句 "d2.direction_flag = 'I'" 在 where 条件下是无用的。
【讨论】:
以上是关于SQL - 在同一个表中匹配相同的值,不同的列的主要内容,如果未能解决你的问题,请参考以下文章
如何在具有相同 ID 的列中选择不同的值然后删除它们 PHP SQL Server