Where分组ID分组

时间:2016-12-15 10:36:20

标签: sql-server tsql

我有以下表格:

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有2条记录,那么包含SQL作为源的记录将是此处使用的记录。

但是,如果有两个相同的ID,它们都有SAP作为源,则都需要忽略。

所以,在这种情况下,结果将是:

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

这个问题类似于the one I asked yesterday,但是我仍然需要忽略SAP中的dubbels。

有任何建议/想法吗?

6 个答案:

答案 0 :(得分:2)

计算每个ID的记录,并获取计数为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 :(得分: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

答案 2 :(得分: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

您应该能够调整此方法以及上一个问题的答案中显示的方法,以便以合理的方式磨练您的搜索条件。

答案 3 :(得分: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;

答案 4 :(得分:1)

relative path

返回

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 

答案 5 :(得分:0)

通过精美的例子,请找到两种方法来完成这个。

一个使用'Having Count'而另一个使用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';