Sql server 从调查答案矩阵中获取回答数
我有一个存储幸福问题答案的表格。结构如下:Sql server 从调查答案矩阵中获取回答数,sql-server,pivot,Sql Server,Pivot,我有一个存储幸福问题答案的表格。结构如下: Wellbeing(WellbeingId, WellbeingDate, Q1, Q2, Q3, Q4, Q5, Q6, Q7...) +------------+---------------+----+----+----+ |WellbeingId | WellbeingDate | Q1 | Q2 | Q3 |... +============+===============+====+====+====+ |1 | 01
Wellbeing(WellbeingId, WellbeingDate, Q1, Q2, Q3, Q4, Q5, Q6, Q7...)
+------------+---------------+----+----+----+
|WellbeingId | WellbeingDate | Q1 | Q2 | Q3 |...
+============+===============+====+====+====+
|1 | 01/01/2015 | 1 | 1 | 5 |
+------------+---------------+----+----+----+
|2 | 10/01/2015 | 3 | 3 | 2 |
+------------+---------------+----+----+----+
|3 | 18/01/2015 | 2 | 4 | 1 |
+------------+---------------+----+----+----+
井眼响应(响应ID、响应文本)
每个Q
列都有一个介于1
和5
之间的值。这些值与相关文本的另一个表相链接(即1=不太多,5=始终等)
我希望从SQL Server获取数据,作为每个可能响应值的总计数,如下所示:
+-------------------+----------+----------+-------------+
|Response | Q1 Total | Q2 Total | Q3 Total ...|
+===================+==========+==========+=============+
|'None of the Time' | 500 | 256 | 546 |
+-------------------+----------+----------+-------------+
|'Rarely' | 500 | 256 | 546 |
+-------------------+----------+----------+-------------+
|'Sometimes' | 500 | 256 | 546 |
+-------------------+----------+----------+-------------+
我已经尝试过选择数据的各个位并使用union all it,但它只是将数据堆叠为7个“Q”列中5个值的计数,我还尝试调整我在某处找到的pivot查询,但在尝试为从WellbeingResponses
表中选择的列使用动态数据时无法理解
任何帮助都将不胜感激
编辑:添加了幸福感回应表。你的
幸福感
表有点乱。我真的建议重写这个表以使其规范化,这样您就可以避免执行多个连接,甚至不必为获得所需的结果而取消对数据的调用
因为您当前的表是非规范化的,所以您必须转换数据以使其可用,然后对其进行聚合,最后将其重新生成最终所需的结果。这会有点混乱,但有几种方法可以做到这一点
获得结果的一种方法是取消打印幸福
表,以便对数据进行规范化。由于您使用的是SQL Server,因此可以使用UNPIVOT
功能,或者根据版本的不同,可以使用交叉应用
。将多列转换为多行的代码如下:
select col, value
from wellbeing
cross apply
(
select 'Q1', Q1 union all
select 'Q2', Q2 union all
select 'Q3', Q3
) c (col, value);
看。这将以以下格式获取您的数据:
| COL | VALUE |
|-----|-------|
| Q1 | 1 |
| Q2 | 1 |
| Q3 | 5 |
| Q1 | 3 |
| Q2 | 3 |
现在,数据可以轻松地与其他表连接:
select r.ResponseText, d.col
from WellbeingResponses r
left join
(
select col, value
from wellbeing
cross apply
(
select 'Q1', Q1 union all
select 'Q2', Q2 union all
select 'Q3', Q3
) c (col, value)
) d
on r.responseid = d.value
看。一旦你得到了每个问题和回答的列表,你就可以将其汇总起来,并以总数为轴心:
select ResponseText, q1, q2, q3
from
(
select r.ResponseText, d.col
from WellbeingResponses r
left join
(
select col, value
from wellbeing
cross apply
(
select 'Q1', Q1 union all
select 'Q2', Q2 union all
select 'Q3', Q3
) c (col, value)
) d
on r.responseid = d.value
) s
pivot
(
count(col)
for col in (Q1, Q2, Q3)
) piv
看
获得结果的另一种方法是在健康状况表上执行多个联接。每个连接都位于问题列:
select r.responsetext,
Q1Total = count(w1.q1),
Q2Total = count(w2.q2),
Q3Total = count(w3.q3)
from WellbeingResponses r
left join wellbeing w1
on r.responseid = w1.q1
left join wellbeing w2
on r.responseid = w2.q2
left join wellbeing w3
on r.responseid = w3.q3
group by r.responsetext;
看。两个版本都将给出一个结果:
| RESPONSETEXT | Q1TOTAL | Q2TOTAL | Q3TOTAL |
|------------------|---------|---------|---------|
| All of the time | 0 | 0 | 1 |
| Most of the time | 0 | 1 | 0 |
| None of the Time | 1 | 1 | 1 |
| Rarely | 1 | 0 | 1 |
| Sometimes | 1 | 1 | 0 |
为此,我将研究交叉应用(一般来说,作为数据库查询的新手,不使用交叉应用)。我可能必须看看是否可以重新构造数据库,使操作更容易…尽管这意味着要在网站上更改一些内容。@bowfinger我添加了另一种解决方案,使用多个联接。最大的问题是您当前的结构,很难使用。我想这是我最初尝试的方式,但我首先从Wellbeing表中选择,然后将WellbeingResponses表内部连接(因为任何值都不能为null)。这看起来既糟糕又低效……可能更需要重组。在您的原始答案中,我在哪里添加ORDER BY子句以获得顺序为1-5的响应文本?@bowfinger您可以在子查询中包含responseid
,然后按它排序-请参阅此演示-非常感谢您的帮助。我想我需要复习一下我的SQL!
| RESPONSETEXT | Q1TOTAL | Q2TOTAL | Q3TOTAL |
|------------------|---------|---------|---------|
| All of the time | 0 | 0 | 1 |
| Most of the time | 0 | 1 | 0 |
| None of the Time | 1 | 1 | 1 |
| Rarely | 1 | 0 | 1 |
| Sometimes | 1 | 1 | 0 |