2015-03-02 38 views
1

我有一张表,可以存储对幸福问题的回答。结构是:获得调查答案矩阵的回复数

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 | 
+------------+---------------+----+----+----+ 

WellbeingResponses(ResponseId,responseText的)

+-----------+---------------------+ 
|ResponseId | ResponseText  | 
+===========+=====================+ 
|1   | 'None of the Time' | 
+-----------+---------------------+ 
|2   | 'Rarely'   | 
+-----------+---------------------+ 
|3   | 'Sometimes'   | 
+-----------+---------------------+ 
|4   | 'Most of the time' | 
+-----------+---------------------+ 
|5   | 'All of the time' | 
+-----------+---------------------+ 

每个Q列具有15(含)之间的值。这些值链接到关联文本的另一个表(即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它但只是堆叠的数据作为从各7“Q的每一个的5个值的计数“列,也尝试调整我在某处找到的数据透视查询,但在尝试使用动态数据查找从WellbeingResponses表中选择列的数据时无法计算出该数据。

任何帮助将不胜感激。

编辑:增加幸福感反应表。

回答

2

您的Wellbeing表有点混乱。我真的建议重写这张表进行规范化处理,这样你就可以避免执行多个连接,甚至不需要转换数据来获得你想要的结果。

由于您的当前表格是非规范化的,因此您必须转换数据以使其可行,然后将其聚合,最后将其重新转换为您的最终期望结果。这会有点混乱,但有几种方法可以做到这一点。

您可以得到结果的一种方法是取消转换您的wellbeing表,以使数据标准化。由于您使用的是SQL Server,因此可以使用UNPIVOT函数,或者根据版本,可以使用CROSS APPLY。将多列转换为多行的代码将为:

select col, value 
from wellbeing 
cross apply 
(
    select 'Q1', Q1 union all 
    select 'Q2', Q2 union all 
    select 'Q3', Q3 
) c (col, value); 

请参阅Demo。这得到你的数据格式:

| 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 

Demo。一旦你得到了每一个问题和响应的列表,你可以聚合它,并转动总计:

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 

SQL Fiddle with Demo

获得结果的另一种方法是在wellbeing表上执行多个连接。每个加入将是对question列:

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; 

Demo。这两个版本都会给出结果:

|  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 | 
+0

感谢您的理解,我会研究跨应用(不是用来作为数据库查询的新手)。我可能不得不查看是否可以对数据库进行重组,以便更轻松地进行操作......尽管这意味着要在网站上更改一些内容。 – bowfinger 2015-03-02 17:31:29

+0

@bowfinger我添加了一个替代解决方案,使用多个连接。最大的问题是你目前的结构,很难合作。 – Taryn 2015-03-02 17:32:47

+0

我认为这是我最初尝试这样做的方式,但是我先从Wellbeing表中选择,然后将内部联接(因为没有值永远不能为null)到WellbeingResponses表。它看起来很肮脏和低效......可能是重组的原因。在您的原始答案中,我将在哪里添加ORDER BY子句以获得1至5的响应文本? – bowfinger 2015-03-02 17:46:54