【问题标题】:SQL Server 2008 : select members group by with conditionsSQL Server 2008:按条件选择成员分组
【发布时间】:2014-02-27 17:31:00
【问题描述】:

我有一张桌子

CREATE TABLE #tblA (mem_id int, type varchar(20), address1 varchar(20),group_id int)

insert into #tblA (mem_id, type, address1,group_id)
values (1,'self','abc St',1),
       (2,'Child','abc St',1),
       (3,'Child','xyz st',1),
       (4,'spouse','pqr st',1),
       (5,'Child','abc St',1),
       (6,'Child','xyz st',1),

       (7,'self','mno st',2),
       (8,'Child','def St',2),
       (9,'Child','def st',2),

       (10,'self','loi st',3),
       (11,'Child','loi St',3),
       (12,'Child','ewr st',3)

       (13,'self','ooo st',NULL),

所以,我要选择:

  1. 对于每个组,选择“self”。
  2. 如果没有组,请选择 self。
  3. 如果其他人住在与自己不同的地址,请选择那些 成员。
  4. 如果多个成员居住在不同的地址,请选择 1 个居住的成员 在不同的地址

所以预期的结果:

   (1,'self','abc St',1),
   (3,'Child','xyz st',1),
   (4,'spouse','pqr st',1),
   (7,'self','mno st',2),
   (8,'Child','def St',2),
   (10,'self','loi st',3),
   (12,'Child','ewr st',3)
   (13,'self','ooo st',NULL),

谢谢

我的代码:不工作:

select  
   mem_id
from 
   (select 
        a.*,
        RANK() over (partition by group_id order by AddressCnt DESC) as AddressRank
    from 
        (select 
             a.*,
             (case when max(address1) over (partition by group_id) = min(address1) over (partition by group_id)
              then 1 else 0
              end) as AddressSame,
             count(*) over (partition by group_id, address1) as AddressCnt
         from #tblA a) a
   ) a
where 
   (AddressSame = 1 or type in ('Self') or
    (AddressRank > 1 OR  type in ('Self') or group_id is null 

【问题讨论】:

    标签: sql-server group-by


    【解决方案1】:

    这里有一个解决方案。

    • 创建一个识别“自我”记录的 CTE。
    • 创建另一个 cte,通过从 self 到 tableA 的连接来识别“others”
    • 使用 row_number 只为另一条记录查找一条记录
    • 联合两个 cte 的


    WITH self 
         AS (SELECT * 
             FROM   tbla 
             WHERE  type = 'self'), 
         others 
         AS (SELECT a.mem_id, 
                    a.type, 
                    a.address1, 
                    a.group_id, 
                    Row_number() 
                      OVER ( 
                        partition BY a.group_id, a.address1 
                        ORDER BY a.mem_id) rn 
             FROM   self s 
                    INNER JOIN tbla a 
                            ON s.group_id = a.group_id 
                               AND s.mem_id <> a.mem_id --Exclude self records
                               AND s.address1 <> a.address1 --Exclude the same address as self) 
    SELECT mem_id, 
           type, 
           address1, 
           group_id 
    FROM   self 
    UNION 
    SELECT mem_id, 
           type, 
           address1, 
           group_id 
    FROM   others 
    WHERE  rn = 1 
    ORDER  BY mem_id 
    

    DEMO

    【讨论】:

      【解决方案2】:

      这个 MySQL 查询给出了所需的输出:

      select * from tblA with type='self' UNION select * from tblA group by address1 没有 address1 (select address1 from tblA where type='self') ORDER by mem_id;

      【讨论】:

      • 这个问题被标记为sql-server。您的语法在 sql server 中不起作用,因为所有列都必须位于聚合函数或 group by 子句中。
      • 是的......你说得对......上面的查询在 SQL 服务器上不起作用
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多