sys*_*out 9 sql sql-server sql-server-2008
我有三个看起来像这样的表:
PROD
Prod_ID|Desc
------------
P1|Foo1
P2|Foo2
P3|Foo3
P4|Foo4
...
Run Code Online (Sandbox Code Playgroud)
内存
Ram_ID|Desc
------------
R1|Bar1
R2|Bar2
R3|Bar3
R4|Bar4
...
Run Code Online (Sandbox Code Playgroud)
PROD_RAM
Prod_ID|Ram_ID
------------
P1|R1
P2|R2
P3|R1
P3|R2
P3|R3
P4|R3
P5|R1
P5|R2
...
Run Code Online (Sandbox Code Playgroud)
在PROD和RAM之间,PROD_RAM表描述了多对多关系.
给定一个Ram_ID像(R1,R3)我想要找到的所有PROD具有给定集合中的一个或全部的RAM集合.
给定(R1,R3)应该返回例如P1,P4和P5; P3不应该被返回,因为有R1和R3也R2.
什么是让所有的最快的查询PROD具有正是ONE或全部的Ram_ID给定的RAM一组?
编辑:
该PROD_RAM表可能包含大于1-> 3的关系,因此,"硬编码"检查count = 1 OR = 2不是一个可行的解决方案.
您可以尝试提高速度的另一种解决方案是这样的
;WITH CANDIDATES AS (
SELECT pr1.Prod_ID
, pr2.Ram_ID
FROM PROD_RAM pr1
INNER JOIN PROD_RAM pr2 ON pr2.Prod_ID = pr1.Prod_ID
WHERE pr1.Ram_ID IN ('R1', 'R3')
)
SELECT *
FROM CANDIDATES
WHERE CANDIDATES.Prod_ID NOT IN (
SELECT Prod_ID
FROM CANDIDATES
WHERE Ram_ID NOT IN ('R1', 'R3')
)
Run Code Online (Sandbox Code Playgroud)
或者如果您不喜欢重复设定的条件
;WITH SUBSET (Ram_ID) AS (
SELECT 'R1'
UNION ALL SELECT 'R3'
)
, CANDIDATES AS (
SELECT pr1.Prod_ID
, pr2.Ram_ID
FROM PROD_RAM pr1
INNER JOIN PROD_RAM pr2 ON pr2.Prod_ID = pr1.Prod_ID
INNER JOIN SUBSET s ON s.Ram_ID = pr1.Ram_ID
)
, EXCLUDES AS (
SELECT Prod_ID
FROM CANDIDATES
LEFT OUTER JOIN SUBSET s ON s.Ram_ID = CANDIDATES.Ram_ID
WHERE s.Ram_ID IS NULL
)
SELECT *
FROM CANDIDATES
LEFT OUTER JOIN EXCLUDES ON EXCLUDES.Prod_ID = CANDIDATES.Prod_ID
WHERE EXCLUDES.Prod_ID IS NULL
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1840 次 |
| 最近记录: |