我有两个表
table1
和table2
,都有列group
、element_id1
、element_id2
、date
。
对于每个 date
和每个 group
,该组中有多个元素。每个元素都有 2 个 id(每个 element_id1
都映射到一个 element_id2
,反之亦然,但有时其中一个可以是 NULL
[存在但未记录在我们的该行表中])。
我想找到每个 group
和 date
在一个表中但不在另一个表中的元素。为了检查两个元素是否相等,我将它们匹配到 element_id1
或 element_id2
(取决于哪一个是非 NULL
)。
例如,让表格为:
组 | 元素_id1 | 元素_id2 | 日期 |
---|---|---|---|
G1 | 1 | 空 | 2024 年 1 月 31 日 |
G1 | 2 | B | 2024 年 1 月 31 日 |
G1 | 3 | C | 2024 年 1 月 31 日 |
G1 | 空 | A | 2024 年 2 月 2 日 |
G1 | 4 | D | 2024 年 2 月 2 日 |
G2 | 1 | A | 2024 年 1 月 31 日 |
G2 | 5 | 空 | 2024 年 2 月 2 日 |
组 | 元素_id1 | 元素_id2 | 日期 |
---|---|---|---|
G1 | 1 | A | 2024 年 1 月 31 日 |
G1 | 空 | B | 2024 年 1 月 31 日 |
G1 | 空 | A | 2024 年 2 月 2 日 |
G1 | 4 | 空 | 2024 年 2 月 2 日 |
G2 | 1 | A | 2024 年 1 月 31 日 |
G2 | 空 | F | 2024 年 2 月 2 日 |
我想要的结果是
组 | 元素_id1 | 元素_id2 | 日期 | 状态 |
---|---|---|---|---|
G1 | 3 | C | 2024 年 1 月 31 日 | 表 2 中缺失 |
G2 | 5 | 空 | 2024 年 2 月 2 日 | 表 2 中缺失 |
G2 | 空 | F | 2024 年 2 月 2 日 | 表 1 中缺失 |
我想在表中设置INDEX。这里有哪些好的指数?我应该对 (
group
, date
, element_id1
, element_id2
) 的组合建立索引吗?但问题有时是 elemet_id
之一是 NULL
。我可以只对两个表中的组和日期建立索引吗?
我使用的SQL如下,但是非常慢:
SELECT COALESCE(t1.group, t2.group) as [Group],
COALESCE(t1.element_id1, t2.element_id1) as element_id1,
COALESCE(t1.element_id2, t2.element_id2) as element_id2,
COALESCE(t1.[date], t2.[date]) as [date],
CASE WHEN t1.[date] IS NULL THEN 'Missing from table1'
ELSE 'Missing from table2'
END AS [Status]
FROM
table1 t1
FULL JOIN
table2 t2
ON t1.[group] = t2.[group]
AND t1.[date] = t2.[date]
AND (t1.element_id1 = t2.element_id1 OR t1.element_id2 = t2.element_id2)
WHERE t1.[date] IS NULL OR t2.[date] IS NULL
OR 条件将成为限制。
对此的优化可以是拆分查询并将所有结果合并,或者反转逻辑并使用 AND 而不是 OR。
例如;
SELECT
*, 'Missing from T2'
FROM
T1
WHERE
NOT EXISTS (
SELECT *
FROM T2
WHERE T2.group = T1.group
AND T2.[date] = T1.[date]
AND T2.element_id1 = T1.element_id1
)
AND NOT EXISTS (
SELECT *
FROM T2
WHERE T2.group = T1.group
AND T2.[date] = T1.[date]
AND T2.element_id2 = T1.element_id2
)
UNION ALL
SELECT
*, 'Missing from T1'
FROM
T2
WHERE
NOT EXISTS (
SELECT *
FROM T1
WHERE T1.group = T2.group
AND T1.[date] = T2.[date]
AND T1.element_id1 = T2.element_id1
)
AND NOT EXISTS (
SELECT *
FROM T1
WHERE T1.group = T2.group
AND T1.[date] = T2.[date]
AND T1.element_id2 = T2.element_id2
)
那么两个表应该各有两个索引:
(group, [date], element_id1)
(group, [date], element_id2)
这是大量的代码重复,但这也是一个不寻常的表设置和要求。