0

嘿伙计们,我有以下要查询的示例数据。

MemberID            AGEQ1       AGEQ2       AGEQ2 
-----------------------------------------------------------------
1217                2           null        null        
58458               3           2           null            
58459               null        null        null            
58457               null        5           null            
299576              6           5           7

我需要做的是查找表,如果任何 AGEx COLUMN 包含任何数据,那么它会计算每列中该行的数据的次数

结果示例:

对于 memberID 1217,计数为 1

对于 memberID 58458,计数为 2

对于 memberID 58459,计数将为 0 或 null

对于 memberID 58457,计数为 1

对于 memberID 299576,计数为 3

如果我查询整个表,这就是它在 SQL 中的样子

1 名儿童 - 2

2 名儿童 - 1

3 名儿童 - 1

0 名儿童 - 1

到目前为止,我一直在使用以下查询进行此操作,该查询效率不高,并且确实给出了不正确的计数,因为人们可以回答 AGE 问题的多种组合。此外,我必须编写多个查询并将 is null 更改为 not null,具体取决于我要计算一个人有多少孩子

select COUNT (*) as '1 Children' from Member
where AGEQ1 is not null
and AGEQ2 is null
and AGEQ3 is null

上面的查询只给了我 1 的答案,但我也希望能够计算其他列的数据

希望这很好,很清楚,提前谢谢你

4

3 回答 3

2

如果所有列都是整数,您可以利用整数数学 - 将列除以自身将产生 1,除非值为 NULL,在这种情况下 COALESCE 可以将结果 NULL 转换为 0。

SELECT 
    MemberID,
    COALESCE(AGEQ1 / AGEQ1, 0)
  + COALESCE(AGEQ2 / AGEQ2, 0)
  + COALESCE(AGEQ3 / AGEQ3, 0)
  + COALESCE(AGEQ4 / AGEQ4, 0)
  + COALESCE(AGEQ5 / AGEQ5, 0)
  + COALESCE(AGEQ6 / AGEQ6, 0)
FROM dbo.table_name; 

要获得每个孩子的人数,然后:

;WITH y(y) AS 
(
  SELECT TOP (7) rn = ROW_NUMBER() OVER 
    (ORDER BY [object_id]) - 1 FROM sys.objects
),
x AS
( 
  SELECT 
     MemberID,
     x = COALESCE(AGEQ1 / AGEQ1, 0)
       + COALESCE(AGEQ2 / AGEQ2, 0)
       + COALESCE(AGEQ3 / AGEQ3, 0)
       + COALESCE(AGEQ4 / AGEQ4, 0)
       + COALESCE(AGEQ5 / AGEQ5, 0)
       + COALESCE(AGEQ6 / AGEQ6, 0)
  FROM dbo.table_name
)
SELECT 
  NumberOfChildren = y.y, 
  NumberOfPeopleWithThatMany = COUNT(x.x) 
FROM y LEFT OUTER JOIN x ON y.y = x.x
GROUP BY y.y ORDER BY y.y; 
于 2013-11-14T03:42:46.510 回答
1

试试这个:

select id, a+b+c+d+e+f 
  from ( select id,
                case when age1 is null then 0 else 1 end a,
                case when age2 is null then 0 else 1 end b,
                case when age3 is null then 0 else 1 end c,
                case when age4 is null then 0 else 1 end d,
                case when age5 is null then 0 else 1 end e,
                case when age6 is null then 0 else 1 end f
          from ages 
       ) as t

请参阅这里的小提琴http://sqlfiddle.com/#!3/88020/1

获取有孩子的人数

select childs, count(*) as ct
  from (
         select id, a+b+c+d+e+f childs
           from
               (
                select
                      id,
                      case when age1 is null then 0 else 1 end a,
                      case when age2 is null then 0 else 1 end b,
                      case when age3 is null then 0 else 1 end c,
                      case when age4 is null then 0 else 1 end d,
                      case when age5 is null then 0 else 1 end e,
                      case when age6 is null then 0 else 1 end f
                  from ages ) as t
               ) ct
   group by childs
   order by 1

在小提琴http://sqlfiddle.com/#!3/88020/24上看到它

于 2013-11-14T03:42:58.207 回答
1

我会考虑使用UNPIVOT。这将使您的宽列变成行。由于您不关心列中的值,只关心值的存在/不存在,这将为每个非空列生成一行。

然后,技巧就变成了将其混合成所需的输出格式。它本可以做得更干净,但我喜欢“展示我的作品”,以便其他人可以使其符合他们的需求。

SQLFiddle

-- Using the above logic
WITH HadAges AS
(
    -- Find everyone and determine number of rows
    SELECT
        UP.MemberID
    ,   count(1) AS rc
    FROM 
        dbo.Member AS M
        UNPIVOT
        (
        ColumnValue for ColumnName in (AGEQ1, AGEQ2, AGEQ3)
        ) AS UP
    GROUP BY
        UP.MemberID
)
, NoAge AS
(
    -- Account for those that didn't show up
    SELECT M.MemberID
    FROM
        dbo.Member AS M
    EXCEPT
    SELECT
        H.MemberID
    FROM
        HadAges AS H
)
, NUMBERS AS
(
    -- Allowable range is 1-6
    SELECT TOP 6
        ROW_NUMBER() OVER (ORDER BY (SELECT NULL))  AS TheCount
    FROM
        sys.all_columns AS SC
)
, COMBINATION AS
(
    -- Link those with rows to their count
    SELECT
        N.TheCount AS ChildCount
    ,   H.MemberID
    FROM
        NUMBERS AS N
        LEFT OUTER JOIN
            HadAges AS H
            ON H.rc = N.TheCount
    UNION ALL
    -- Deal with the unlinked
    SELECT
        0
    ,   NA.MemberID
    FROM
        NoAge AS NA
)
SELECT
    C.ChildCount
,   COUNT(C.MemberID) AS Instances
FROM
    COMBINATION AS C
GROUP BY
    C.ChildCount;
于 2013-11-14T04:30:47.367 回答