제출 된 값의 최소 SET을 포함하는 결과 집합을 쿼리하고 얻는 방법
Aug 21 2020
WITH fData AS
(
SELECT 1001 AS lookupID, 'A' AS LookUpValue UNION ALL
SELECT 1001 AS lookupID, 'B' AS LookUpValue UNION ALL
SELECT 1001 AS lookupID, 'C' AS LookUpValue UNION ALL
SELECT 1001 AS lookupID, 'D' AS LookUpValue UNION ALL
SELECT 1002 AS lookupID, 'A' AS LookUpValue UNION ALL
SELECT 1002 AS lookupID, 'Z' AS LookUpValue UNION ALL
SELECT 1002 AS lookupID, 'S' AS LookUpValue UNION ALL
SELECT 1002 AS lookupID, 'J' AS LookUpValue UNION ALL
SELECT 1003 AS lookupID, 'H' AS LookUpValue UNION ALL
SELECT 1003 AS lookupID, 'I' AS LookUpValue UNION ALL
SELECT 1003 AS lookupID, 'Z' AS LookUpValue UNION ALL
SELECT 1003 AS lookupID, 'C' AS LookUpValue
)
SELECT *
FROM fData fd
WHERE fd.LookUpValue IN ('A','B','C','D') /* This pulls back ANY record having these values and then return all of the records in that list. I want ONLY lists that have a minimum of these values. For example of my list only contained 'A' I would see both List 1001 records and List 1002 Records. */
;
내가 제공 한 코드에는 세 개의 가짜 목록이 포함되어 있습니다. 각 목록에는 값 집합이 포함되어 있습니다. 지정한 값이 포함 된 목록의 모든 레코드를 제공하는 쿼리를 어떻게 작성합니까? IN 문을 사용하면 해당 목록 값을 포함하는 모든 목록 (레코드)이 제공되므로 작동하지 않습니다. 대신 내가 지정한 값을 모두 포함하는 목록 레코드 만 반환하면됩니다.
내 예에서는 4 개의 값 ( 'A', 'B', 'C', 'D')을 제공 했으므로 결과 집합에서 lookupID가 1001 인 첫 번째 목록의 레코드 만 볼 수 있습니다. 예를 들어 단일 항목을 제출하면 'A'의 값 그런 다음 목록 1001 및 목록 1002에 대한 모든 레코드를 볼 수 있습니다. 두 목록 모두 최소 'A'값을 포함하기 때문입니다. 목록 1003에는 'A'값이 없습니다.
답변
3 forpas Aug 21 2020 at 18:02
lookupID
이 쿼리로 원하는를 얻습니다 .
SELECT lookupID
FROM fData
WHERE LookUpValue IN ('A','B','C','D')
GROUP BY lookupID
HAVING COUNT(DISTINCT LookUpValue) = 4 -- the number of searched lookupvalues
연산자를 사용하여 테이블의 모든 행 IN
:
SELECT * FROM fData
WHERE lookupID IN (
SELECT lookupID
FROM fData
WHERE LookUpValue IN ('A','B','C','D')
GROUP BY lookupID
HAVING COUNT(DISTINCT LookUpValue) = 4
)
코드는 표준 SQL이며 내가 아는 모든 데이터베이스에서 작동합니다. 데모를
참조하십시오 . 결과 :
> lookupID | LookUpValue
> -------: | :----------
> 1001 | A
> 1001 | B
> 1001 | C
> 1001 | D
dnoeth Aug 21 2020 at 21:51
Group By 대신 Windowed Aggregates 를 사용하는 forpas 쿼리의 변형
WITH fData AS
(
SELECT 1001 AS lookupID, 'A' AS LookUpValue UNION ALL
SELECT 1001 AS lookupID, 'B' AS LookUpValue UNION ALL
SELECT 1001 AS lookupID, 'C' AS LookUpValue UNION ALL
SELECT 1001 AS lookupID, 'D' AS LookUpValue UNION ALL
SELECT 1001 AS lookupID, 'E' AS LookUpValue UNION ALL
SELECT 1002 AS lookupID, 'A' AS LookUpValue UNION ALL
SELECT 1002 AS lookupID, 'Z' AS LookUpValue UNION ALL
SELECT 1002 AS lookupID, 'S' AS LookUpValue UNION ALL
SELECT 1002 AS lookupID, 'J' AS LookUpValue UNION ALL
SELECT 1003 AS lookupID, 'H' AS LookUpValue UNION ALL
SELECT 1003 AS lookupID, 'I' AS LookUpValue UNION ALL
SELECT 1003 AS lookupID, 'Z' AS LookUpValue UNION ALL
SELECT 1003 AS lookupID, 'C' AS LookUpValue
),
cte as
(
SELECT *,
count(case when LookUpValue IN ('A','B','C','D') then 1 end)
over (partition by lookupID) as cnt
FROM fData
)
select lookupID, LookUpValue
from cte
where cnt = 4
이것은 lookupID | LookUpValue 조합이 고유 한 경우에만 작동합니다 (DISTINCT를 제거하여 forpas 쿼리를 단순화 할 수도 있음).
바이올린 참조