Sql-Server

查詢每個不同 A 的表 1 (A,B,C) 中的行與表 2 (B,C) 中的所有行匹配的行

  • February 2, 2019

我正在嘗試在這裡優化查詢:

給定表 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
                                       )
                   );

引用自:https://dba.stackexchange.com/questions/205881