时间:2018-02-23 04:18:54

标签: sql-server sql-server-2012

我不知道标题是否符合我在下面给出的查询中尝试实现的内容。这个例子可能不是很好,但它符合我的目标。我想要获得三个结果,如下所示。这可以通过单个查询以更好的方式显示所有结果吗?

TABLE:

name    surname gender
arjun   khadka  female
arjun   khadka  male
arjun   basnet  male
kumar   khadka  female
kumar   basnet  female
arjun   khadka  female
arjun   basnet  female
kumar   khadka  female

查询:

    WITH cte
    AS (SELECT
      *,
      DENSE_RANK() OVER (ORDER BY name, surname) AS groupid1,
      DENSE_RANK() OVER (ORDER BY name, surname, gender) AS groupid2
    FROM (SELECT
      name,
      surname,
      gender

   FROM name) x)
  1. 同一个人,有重复的性别以及非重复的人 性别

      SELECT
      name,
      surname,
      gender
    FROM CTE
    WHERE groupid1 IN (SELECT
      groupid1
    FROM cte
    GROUP BY groupid1,
             groupid2
    HAVING COUNT(*) > 1)
    AND groupid1 IN (SELECT
      groupid1
    FROM cte
    GROUP BY groupid1,
             groupid2
    HAVING COUNT(*) = 1)
    
  2. 完全没有性别重复的同一个人

    SELECT
      *
    FROM cte
    WHERE groupid1 NOT IN (SELECT
      groupid1
    FROM cte
    GROUP BY groupid1,
             groupid2
    HAVING COUNT(*) > 1)
    
  3. 只有重复性别记录的同一个人

    SELECT
      *
    FROM cte
    WHERE groupid1 IN (SELECT
      groupid1
    FROM cte
    GROUP BY groupid1,
             groupid2
    HAVING COUNT(*) > 1)
    AND groupid1 NOT IN (SELECT
      groupid1
    FROM cte
    GROUP BY groupid1,
             groupid2
    HAVING COUNT(*) = 1)
    
  4. 我修改了@uzi提供的内容,作为解决方案,因为它有一些缺陷:

            select
               distinct  name, surname,personCount as count
                , personHasDupNUniqueGender = iif(min(allRowsCount) over (partition by personGroupId) = 1 and max (allRowsCount) over (partition by personGroupId) >1,1,0)
                , personHasUniqueGender = iif(max(allRowsCount) over (partition by personGroupId) = 1,1,0)
                , personHasAllDupGender = iif(personCount = allrowscount and personcount>1,1,0)
            from (
                select 
                   *
                    , personGroupId= DENSE_RANK() over (order by name, surname)
                    , personCount = count(*) over (partition by name, surname)
                     , allRowsCount = count(*) over (partition by name, surname, gender)
                from 
                    name
            ) t
    
            order by name, surname
    

1 个答案:

答案 0 :(得分:1)

这是一种方式。查询返回具有额外列condition_1, condition_2, condition_3的所有行。这些列的值为1或0. 1 - 匹配条件

declare @t table (
    name varchar(100)
    , surname varchar(100)
    , gender varchar(100)
)
insert into @t values 
('arjun', 'khadka', 'female')
,('arjun', 'khadka', 'male')
,('arjun', 'basnet', 'male')
,('kumar', 'khadka', 'female')
,('kumar', 'basnet', 'female')
,('arjun', 'khadka', 'female')
,('arjun', 'basnet', 'female')
,('kumar', 'khadka', 'female')

select
    name, surname, gender
    , condition_1 = max(iif(cnt_1 = 1 and cnt_2 > 2, 1, 0)) over (partition by name, surname)
    , condition_2 = iif(cnt_2 - cnt_1 <= 1 and cnt_1 = 1, 1, 0)
    , condition_3 = iif(cnt_2 = cnt_1 and cnt_1 > 1, 1, 0)
from (
    select 
        *, cnt_1 = count(*) over (partition by name, surname, gender)
        , cnt_2 = count(*) over (partition by name, surname)
    from 
        @t
) t
order by name, surname

输出

name    surname   gender   condition_1   condition_2   condition_3
-------------------------------------------------------------------
arjun   basnet    female    0            1             0
arjun   basnet    male      0            1             0
arjun   khadka    female    1            0             0
arjun   khadka    female    1            0             0
arjun   khadka    male      1            0             0
kumar   basnet    female    0            1             0
kumar   khadka    female    0            0             1
kumar   khadka    female    0            0             1

编辑:

select
    name, surname, gender, cnt_1, cnt_2
    , condition_1 = max(iif(cnt_1 = 1 and cnt_2 > 2, 1, 0)) over (partition by name, surname)
    , condition_2 = iif(max(cnt_1) over (partition by name, surname) = 1, 1, 0)
    , condition_3 = iif(cnt_2 = cnt_1 and cnt_1 > 1, 1, 0)
from (
    select 
        *, cnt_1 = count(*) over (partition by name, surname, gender)
        , cnt_2 = count(*) over (partition by name, surname)
    from 
        @t
) t
order by name, surname