SQL:计算多项选择结果的答案
SQL: Counting the answers from a multiple-choice result
我有多项选择题问卷的答复。我的目标是计算回答 'A'、'B' 等问题的受访者人数,并进一步处理该数据。
(原始数据在 JSON 中,但这也可能是 table 数据。JSON 格式并不是一个真正的因素,但如果有更好的方法来获取结果形式 JSON 然后我愿意接受想法)。
我有两种统计回答的方法,但我的方法每个问题只生成一组总数。
方法一:求和
DECLARE @json NVARCHAR(MAX);
SET @json = N'[
{"q1": "B", "q2": "B"},
{"q1": "C", "q2": "C"},
{"q1": "D", "q2": "C"},
{"q1": "A", "q2": "B"},
{"q1": "A", "q2": "B"},
{"q1": "C", "q2": "A"},
{"q1": "C", "q2": "B"}
]';
SELECT
Count(*) as total,
sum(case when q1 = 'A' then 1 else 0 end) as A,
sum(case when q1 = 'B' then 1 else 0 end) as B,
sum(case when q1 = 'C' then 1 else 0 end) as C,
sum(case when q1 = 'D' then 1 else 0 end) as D
FROM OPENJSON(@json)
WITH (
q1 NVARCHAR(50) '$.q1',
q2 NVARCHAR(50) '$.q2'
)
结果:
total
A
B
C
D
7
2
1
3
1
方法二:旋转
DECLARE @json NVARCHAR(MAX);
SET @json = N'[
{"q1": "B", "q2": "B"},
{"q1": "C", "q2": "C"},
{"q1": "D", "q2": "C"},
{"q1": "A", "q2": "B"},
{"q1": "A", "q2": "B"},
{"q1": "C", "q2": "A"},
{"q1": "C", "q2": "B"}
]';
SELECT *
FROM OPENJSON(@json)
WITH (
q1 NVARCHAR(50) '$.q1'
) t
PIVOT(
COUNT(q1)
FOR q1 IN
(
[A],
[B],
[C],
[D]
)
) as pivot_table
结果:
A
B
C
D
2
1
3
1
期望的结果
有没有一种方法可以用一条语句计算出所有问题?
Question
A
B
C
D
q1
2
1
3
1
q2
1
3
2
0
我认为 WITH
可能会得到 q1,q2
而不是 q1,q1
因为q1
和q2
是two-columns我们可以尝试用CROSS APPLY
值做unpivot,然后使用聚合条件函数
SELECT
v.Question,
sum(case when v.val = 'A' then 1 else 0 end) as A,
sum(case when v.val = 'B' then 1 else 0 end) as B,
sum(case when v.val = 'C' then 1 else 0 end) as C,
sum(case when v.val = 'D' then 1 else 0 end) as D
FROM OPENJSON(@json)
WITH (
q1 NVARCHAR(50) '$.q1',
q2 NVARCHAR(50) '$.q2'
)
CROSS APPLY (VALUES ('q1',q1),('q2',q2)) v(Question,val)
GROUP BY v.Question
我有多项选择题问卷的答复。我的目标是计算回答 'A'、'B' 等问题的受访者人数,并进一步处理该数据。
(原始数据在 JSON 中,但这也可能是 table 数据。JSON 格式并不是一个真正的因素,但如果有更好的方法来获取结果形式 JSON 然后我愿意接受想法)。
我有两种统计回答的方法,但我的方法每个问题只生成一组总数。
方法一:求和
DECLARE @json NVARCHAR(MAX);
SET @json = N'[
{"q1": "B", "q2": "B"},
{"q1": "C", "q2": "C"},
{"q1": "D", "q2": "C"},
{"q1": "A", "q2": "B"},
{"q1": "A", "q2": "B"},
{"q1": "C", "q2": "A"},
{"q1": "C", "q2": "B"}
]';
SELECT
Count(*) as total,
sum(case when q1 = 'A' then 1 else 0 end) as A,
sum(case when q1 = 'B' then 1 else 0 end) as B,
sum(case when q1 = 'C' then 1 else 0 end) as C,
sum(case when q1 = 'D' then 1 else 0 end) as D
FROM OPENJSON(@json)
WITH (
q1 NVARCHAR(50) '$.q1',
q2 NVARCHAR(50) '$.q2'
)
结果:
total | A | B | C | D |
---|---|---|---|---|
7 | 2 | 1 | 3 | 1 |
方法二:旋转
DECLARE @json NVARCHAR(MAX);
SET @json = N'[
{"q1": "B", "q2": "B"},
{"q1": "C", "q2": "C"},
{"q1": "D", "q2": "C"},
{"q1": "A", "q2": "B"},
{"q1": "A", "q2": "B"},
{"q1": "C", "q2": "A"},
{"q1": "C", "q2": "B"}
]';
SELECT *
FROM OPENJSON(@json)
WITH (
q1 NVARCHAR(50) '$.q1'
) t
PIVOT(
COUNT(q1)
FOR q1 IN
(
[A],
[B],
[C],
[D]
)
) as pivot_table
结果:
A | B | C | D |
---|---|---|---|
2 | 1 | 3 | 1 |
期望的结果
有没有一种方法可以用一条语句计算出所有问题?
Question | A | B | C | D |
---|---|---|---|---|
q1 | 2 | 1 | 3 | 1 |
q2 | 1 | 3 | 2 | 0 |
我认为 WITH
可能会得到 q1,q2
而不是 q1,q1
因为q1
和q2
是two-columns我们可以尝试用CROSS APPLY
值做unpivot,然后使用聚合条件函数
SELECT
v.Question,
sum(case when v.val = 'A' then 1 else 0 end) as A,
sum(case when v.val = 'B' then 1 else 0 end) as B,
sum(case when v.val = 'C' then 1 else 0 end) as C,
sum(case when v.val = 'D' then 1 else 0 end) as D
FROM OPENJSON(@json)
WITH (
q1 NVARCHAR(50) '$.q1',
q2 NVARCHAR(50) '$.q2'
)
CROSS APPLY (VALUES ('q1',q1),('q2',q2)) v(Question,val)
GROUP BY v.Question