簡體   English   中英

如何選擇具有精確外鍵的主鍵與給定的值列表匹配?

[英]How to select a primary key which has exact foreign keys matches a given list of values?

例如:

pk_ref    fk
======    ===
1         a
1         b
1         c
2         a
2         b
2         d

如何進行“偽”查詢之類的查詢:

select distinc pk_ref
where fk in all('a', 'c');

返回查詢結果必須匹配列表中外鍵的所有給定值。

結果應該是:

1

而以下選擇不得返回任何記錄。

select distinc pk_ref
where fk in all('a', 'c', 'd');

我怎么做?

試試這個

select pk_ref 
from yourtable 
group by pk_ref 
having count(case when fk = 'a',  then 1 end) >= 1 
and count(case when fk = 'c' then 1 end) >= 1

動態地做。 (考慮到你使用的是SQL SERVER)

創建拆分字符串函數並將輸入作為逗號分隔值傳遞

Declare @input varchar(8000)= 'a,c',@cnt int 

set @cnt = len(@input)-len(replace(@input,',','')) + 1

select pk_ref 
from yourtable 
Where fk in (select split_values from udf_splitstring(@input , ','))
group by pk_ref 
having count(Distinct fk) >= @cnt 

您可以從以下鏈接創建拆分字符串函數

https://sqlperformance.com/2012/07/t-sql-queries/split-strings

:list是輸入列表(綁定變量)。 length()返回值的差異是綁定變量中的逗號數。 此查詢或與其非常接近的查詢應該適用於任何數據庫產品。 在Oracle中測試過。

select   pk_ref
from     tbl    --  enter your table name here
where    ',' || :list || ','   like   '%,' || fk || ',%'
group by pk_ref
having   count(distinct fk) = 1 + length(:list) - length(replace(:list, ',', ''))

如果您可以將IN運算符值作為Set傳遞,則可以執行以下操作

架構:

SELECT * INTO #TAB FROM (
SELECT 1 ID, 'a' FK
UNION ALL
SELECT 1, 'b'
UNION ALL
SELECT 1, 'c'
UNION ALL
SELECT 2, 'a'
UNION ALL
SELECT 2, 'b'
UNION ALL
SELECT 2, 'd'
UNION ALL
SELECT 1, 'a'
)AS A

使用CTE將'a','c'設為Set

;WITH CTE AS (
SELECT 'a' FK   --Here 'a','c' passed as a Set through CTE
UNION 
SELECT 'c'
)
,FINAL AS(

SELECT DENSE_RANK() OVER (PARTITION BY ID ORDER BY (FK))AS COUNT_ID, ID, FK 
FROM #TAB where FK  IN (select FK FROM CTE)

)
SELECT ID FROM FINAL WHERE COUNT_ID>=(SELECT COUNT( FK) FROM CTE)
Select pk_ref where fk='a' and pk_ref in (select pk_ref where fk='c' from yourtable) from yourtable;  

要么

select pk_ref where fk='a' from yourtable intersect select pk_ref where fk='c' from yourtable;
    DECLARE @inputVariable VARCHAR(200) =  'a,b,c,d'
    DECLARE @inputValue INT
    DECLARE @tblInput TABLE
    (
        FK VARCHAR(100)
    )




    INSERT INTO @tblInput
    SELECT SUBSTRING( @inputVariable+',',RN,1)
      FROM (SELECT TOP 100 ROW_NUMBER() OVER(ORDER BY s.object_id) RN
      FROM sys.objects s)  s
      where LEN(@inputVariable) >= RN
      AND SUBSTRING(','+ @inputVariable,RN,1) = ','

    SELECT @inputValue = COUNT(1) FROm @tblInput

    --@inputVariable

    DECLARE @tbl TABLE 
    (
        ID INT,
        FK VARCHAR(100) 
    )

    INSERT INTO @tbl
    SELECT 1 ID, 'a' FK
    UNION ALL
    SELECT 1, 'b'
    UNION ALL
    SELECT 1, 'c'
    UNION ALL
    SELECT 2, 'a'
    UNION ALL
    SELECT 2, 'b'
    UNION ALL
    SELECT 2, 'd'
    UNION ALL
    SELECT 1, 'a'

    SELECT t.ID ,COUNT(DISTINCT t.FK) 
      FROM @tbl t
    INNER JOIn @tblInput  ti
            ON t.FK = ti.FK
        GROUP BY ID
        HAVING COUNT(DISTINCT t.FK) = @inputValue

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM