嘿伙计们,我有以下示例数据,我想查询。
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的答案,但我希望能够计算数据的其他列
希望这很好,很清楚,并提前感谢你
答案 0 :(得分:2)
如果所有列都是整数,则可以利用整数数学 - 除非值为NULL,否则将列除以自己将产生1,在这种情况下,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;
答案 1 :(得分: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
中查看
答案 2 :(得分:1)
我会考虑使用UNPIVOT。这将使您的宽列成行。由于您不关心列中的值,只关注值的存在/不存在,这将为每个非空列生成一行。
然后将技巧混合成所需的输出格式。它可能已经做得更干净但我是“展示我的工作”的粉丝,以便其他人可以满足他们的需求。
-- 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;