2016-12-15 77 views
1

我有如下表:Where子句按分組ID的

ID | source | Name | Age | ... | ... 
1 | SQL | John | 18 | ... | ... 
2 | SAP | Mike | 21 | ... | ... 
2 | SQL | Mike | 20 | ... | ... 
3 | SAP | Jill | 25 | ... | ... 
4 | SAP | Jake | 31 | ... | ... 
4 | SAP | Jake | 30 | ... | ... 

我想爲每個ID的一個記錄。這背後的想法是,如果ID只出現一次(不管來源),該記錄將被採取。但是,如果一個ID有兩條記錄,那麼包含SQL作爲源的那條記錄就是這裏使用的記錄。

但是,如果有兩個具有SAP作爲源的相同ID,則都需要忽略。

所以,在這種情況下,結果將是:

ID | source | Name | Age | ... | ... 
1 | SQL | John | 18 | ... | ... 
2 | SQL | Mike | 20 | ... | ... 
3 | SAP | Jill | 25 | ... | ... 

這個問題類似於the one I asked yesterday,但我堅持,我需要忽略來自SAP dubbels的部分。

任何建議/想法?

回答

2

計算每個ID的記錄數,並記錄count爲1或來源爲SQL的記錄。

select id, source, name, age 
from 
(
    select id, source, name, age, count() over (partition by id) as cnt 
    from mytable 
) counted 
where cnt = 1 or source = 'SQL'; 
1
SELECT id,source,name, age 
FROM #f 
WHERE ID in (
    SELECT ID FROM #f 
    group by ID 
    having count(ID) = 1) 
OR source = 'SQL' 

輸出

ID source Name Age 
1 SQL John 18 
2 SQL Mike 20 
3 SAP Jill 25 
1

我們可以計數的行數爲每個ID,然後使用該應用進一步邏輯:

declare @t table (ID int,source varchar(31),Name varchar(17),Age int) 
insert into @t(ID,source,Name,Age) values 
(1,'SQL','John',18), 
(2,'SAP','Mike',21), 
(2,'SQL','Mike',20), 
(3,'SAP','Jill',25), 
(4,'SAP','Jake',31), 
(4,'SAP','Jake',30) 

;With Counted as (
    select 
     *, 
     COUNT(*) OVER (PARTITION BY ID) as cnt 
    from 
     @t 
) 
select 
    * 
from 
    Counted 
where 
    cnt = 1 or 
    (cnt = 2 and source = 'SQL') 

結果:

ID   source       Name    Age   cnt 
----------- ------------------------------- ----------------- ----------- ----------- 
1   SQL        John    18   1 
2   SQL        Mike    20   2 
3   SAP        Jill    25   1 

你應該能夠適應這種方法和那些在你的上一個問題的答案中顯示,以每種有意義的方式磨練你的搜索標準。

1
WITH cte AS (
    SELECT ID, source, Name, Age 
     , ROW_NUMBER() OVER (PARTITION BY ID ORDER BY CASE source WHEN 'SAP' THEN -1 ELSE 1 END CASE) as RN 
    FROM 
     Table 
) 
SELECT ID, source, Name, Age 
FROM cte 
WHERE source <> 'SAP' AND rn = 1; 
1
Declare @YourTable table (ID int,source varchar(25),Name varchar(25), Age int) 
Insert Into @YourTable values 
(1 ,'SQL', 'John', 18 ), 
(2 ,'SAP', 'Mike', 21 ), 
(2 ,'SQL', 'Mike', 20 ), 
(3 ,'SAP', 'Jill', 25 ), 
(4 ,'SAP', 'Jake', 31 ), 
(4 ,'SAP', 'Jake', 30 ) 

Select ID,Source,Name,Age 
From (
     Select * 
       ,RN = Row_Number() over (Partition By ID Order By Case When Source = 'SQL' Then 0 Else 1 End) 
       ,Cnt = sum(1) over (Partition By ID,Source) 
      From @YourTable 
     ) A 
Where RN=1 and Cnt=1 

返回

ID Source Name Age 
1 SQL  John 18 
2 SQL  Mike 20 
3 SAP  Jill 25 
0

通過典範的合作,請找2種方式來完成這一點。

一個使用「有計數」,另一個使用OVER(按ID分區)。

declare @t table (ID int,source varchar(31),Name varchar(17),Age int) 
insert into @t(ID,source,Name,Age) values 
(1,'SQL','John',18), 
(2,'SAP','Mike',21), 
(2,'SQL','Mike',20), 
(3,'SAP','Jill',25), 
(4,'SAP','Jake',31), 
(4,'SAP','Jake',30) 


SELECT * 
FROM @t 
WHERE ID in (
     SELECT ID FROM @t 
     group by ID 
having count(ID) = 1) 
OR source = 'SQL' 

-- alternatively 

select id, source, name, age 
from 
(
    select id, source, name, age, count(*) over (partition by id) as cnt 
    from @t 
) counted 
where cnt = 1 or source = 'SQL';