Sql-Server
查詢每個不同 A 的表 1 (A,B,C) 中的行與表 2 (B,C) 中的所有行匹配的行
我正在嘗試在這裡優化查詢:
給定表 1 (A,B,C) 和表 2 (B,C)
給定表 1 包含每個 A 的許多唯一元組 (B,C)
選擇(1.A、1.B、1.C)
對於 1.A 不同的給定行集,行集必須共同滿足 2 中的所有行,其中 1.B = 2.B 和 1.C = 2.C
例子
表格1
| A | B | C | |---|----|----| | 1 | B1 | C1 | | 1 | B2 | C2 | | 2 | B1 | C1 | | 2 | B2 | C2 | | 2 | B3 | C3 | | 3 | B1 | C1 |
表 2
| B | C | |----|----| | B1 | C1 | | B2 | C2 |
結果
| A | B | C | |---|----|----| | 1 | B1 | C1 | | 1 | B2 | C2 | | 2 | B1 | C1 | | 2 | B2 | C2 | | 2 | B3 | C3 |
(僅排除了 3 個,因為它未能匹配表 2 的兩行)
目前的實現是動態 SQL
select Result.A from ( SELECT vtab1.A FROM table1 vtab1 where vtab1.[B]= 'B1' and vtab1.[C] = 'C1' union all SELECT b.VaultObjectId FROM table1 vtab2 where vtab2.[B]= 'B2' and vtab2.[C] = 'C2' ) AS Result Group By A HAVING COUNT(A) = 2
然而,這都是動態生成的,並且不會將我的 A 與匹配的 B 重新合併(我認為這很容易)
相關:有什麼方法可以“命名”稍後使用的查詢(不是計算的,而是延遲的?)
select * from t1 where t1.a in ( select t1.a from t1 join t2 on t2.b = t1.b and t2.c = t2.c group by t1.a having count(*) = (select count(*) from t2) )
我發現處理關係劃分挑戰的最簡單方法是用否定形式表達問題:“顯示 T1 中的所有行,T2 中不存在行,不存在另一行來自 T1 的行,具有相同的 A 值,並且匹配 B 和 C 值”。一開始看起來很奇怪,但是一旦你習慣了,SQL 的轉換是直接的、優雅的,而且通常是最有效的:
SELECT * FROM T1 WHERE NOT EXISTS ( SELECT NULL FROM T2 WHERE NOT EXISTS ( SELECT NULL FROM T1 AS T1A WHERE T1A.B = T2.B AND T1A.C = T2.C AND T1A.A = T1.A ) );