2017-01-28 86 views
1

我有一個包含項目,部件列表以及部件是否可用的項目表(此例爲非標準化)。我想返回所有可用部件的所有項目。每個項目可以有不同數量的部件。例如:SQL Server-僅在所有子項都可用時返回項目

Item Part Available 
A  1  Y 
A  2  N 
A  3  N 
B  1  Y 
B  4  Y 
C  2  N 
C  5  Y 
D  4  Y 
D  6  Y 
D  7  Y 

查詢應返回如下:

Item Part 
B  1 
B  4 
D  4  
D  6  
D  7  

感謝您的任何援助。

回答

0

這裏使用一個特技Max() Over()窗口集合功能

SELECT Item, 
     Part 
FROM (SELECT Max([Available])OVER(partition BY [Item]) m_av,* 
     FROM yourtable) a 
WHERE m_av = 'Y' 

,或者使用Group ByHaving和子句

使用利用Exists

IN子句

SELECT Item, 
     Part 
FROM yourtable 
WHERE Item IN (SELECT Item 
       FROM yourtable 
       GROUP BY Item 
       HAVING Count(*) = Sum(Iif(Available = 'Y', 1, 0))) 

SELECT Item, 
     Part 
FROM yourtable A 
WHERE EXISTS (SELECT 1 
       FROM yourtable B 
       WHERE A.Item = B.Item 
       HAVING Count(*) = Sum(Iif(Available = 'Y', 1, 0))) 

使用NOT EXISTS

SELECT Item, 
     Part 
FROM yourtable A 
WHERE NOT EXISTS (SELECT * 
        FROM yourtable B 
        WHERE A.Item = B.Item 
          AND B.Available = 'N') 
0

我會用改述需求開始 - 要返回沒有不可用的任何部件的項目。一旦你把它這樣,很容易使用not exists運營商的要求轉化爲SQL:

SELECT item, part 
FROM parts a 
WHERE NOT EXISTS (SELECT * 
        FROM parts b 
        WHERE a.item = b.item AND b.available = 'N') 
0

U可以使用NOT IN OR NOT EXISTS實現這一

NOT EXISTS

Select item, part 
from table as T1 
where not exists(select 1 from tbl where item = t1.item and available = 'N') 

NOT IN

Select item, part 
from table 
where item not in(select item from tbl where available = 'N') 
0

使用窗口函數可以讀取單個表格。

MINMAX窗函數

select * 
from (
    select 
     t.*, 
     max(available) over (partition by item) a, 
     min(available) over (partition by item) b 
    from your_table t 
) t where a = b and a = 'Y'; 

COUNT窗函數:

select * 
from (
    select 
     t.*, 
     count(*) over (partition by item) n1 
     count(case when available = 'Y' then 1 end) over (partition by item) n2 
    from your_table t 
) t where n1 = n2; 
+0

第一種方法是錯誤的,當每個記錄是'N'那麼它將返回項目 –

+0

@Prdp非常感謝。修復。 – GurV

0

我想指出的是,在文本的問題是:「我要回所有的物品,其所有部件都可用「。但是,您的示例結果包含這些部分。

如果問題確實是你想要的物品而已,那麼你可以使用簡單的聚合:

select item 
from parts 
group by item 
having min(available) = max(available) and min(available) = 'Y'; 

如果你確實想在部分細節,以及,那麼其他的答案提供了信息。

0

我喜歡它的問題借給自己很好地通過不經常使用的語言功能正在得到解決:

with cte as (
    select * from (values 
     ('A', 1, 'Y'), 
     ('A', 2, 'N'), 
     ('A', 3, 'N'), 
     ('B', 1, 'Y'), 
     ('B', 4, 'Y'), 
     ('C', 2, 'N'), 
     ('C', 5, 'Y'), 
     ('D', 4, 'Y'), 
     ('D', 6, 'Y'), 
     ('D', 7, 'Y') 
    ) as x(Item, Part, Available) 
) 
select * 
into #t 
from cte as c; 

select * 
from #t as c 
where 'Y' = all (
    select Available 
    from #t as a 
    where c.Item = a.Item 
) 

這裏,我們使用相關子查詢和all關鍵字,看看是否所有的部件都可用。我的理解是,就像exists一樣,如果它找到一個反例,它就會停止。

相關問題