为模糊的标题道歉,但这更像是征求建议而不是寻找直接答案。作为参考,我正在使用SSMS 2014。
我正在使用我没有创建的数据库,而且我正在努力处理当前格式的数据。我已经列出了下表的一个例子。
+-----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|DtID | ID | Mo1 | Mo2 | Tu1 | Tu2 | We1 | We2 | Th1 | Th2 | Fr1 | Fr2 |
+-----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 565 | 12 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 |
| 565 | 13 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
| 565 | 14 | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 0 |
| 565 | 15 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 |
| 572 | 12 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
| 572 | 13 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 |
| 572 | 14 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 |
| 572 | 15 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 |
+-----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
DtID是开始日期标识符的一周,ID是人员标识符,Mo1表示星期一上午,Mo2星期一下午等.1表示参加该会话的人。该表超过600k行。
尝试在特定日期范围之间查询数据时出现问题,例如我想在日期标识566和575之间找到当前出勤标记的总和。日期566表示从565开始的星期二和575指的是从572开始的星期四。
我会更熟悉下面表格中格式化的表格(例如第1行)。
+-----+----+------+---------+
|DtID | ID | AMPM | Present |
+-----+----+------+---------+
| 565 | 12 | 1 | 0 |
| 565 | 12 | 2 | 1 |
| 566 | 12 | 1 | 0 |
| 566 | 12 | 2 | 1 |
| 567 | 12 | 1 | 1 |
| 567 | 12 | 2 | 0 |
| 568 | 12 | 1 | 0 |
| 568 | 12 | 2 | 0 |
| 569 | 12 | 1 | 1 |
| 569 | 12 | 2 | 0 |
+-----+----+------+---------+
这可能吗?是否有一种有效的方式来查询数据?我对SQL很新,到目前为止,我几乎所有的学习都来自于解释本网站上的问题和答案。正如我所说,我真的不知道我正在寻找的答案,所以这里的用户的集体建议和智慧对我来说非常有用。
非常感谢。
答案 0 :(得分:2)
我认为你不想放弃日间信息
select DtID,ID,left(day,2) as day,right(day,1) as AMPM,Present
from t unpivot (Present for day in (Mo1,Mo2,Tu1,Tu2,We1,We2,Th1,Th2,Fr1,Fr2)) t
+------+----+-----+------+---------+
| DtID | ID | day | AMPM | Present |
+------+----+-----+------+---------+
| 565 | 12 | Mo | 1 | 0 |
+------+----+-----+------+---------+
| 565 | 12 | Mo | 2 | 1 |
+------+----+-----+------+---------+
| 565 | 12 | Tu | 1 | 0 |
+------+----+-----+------+---------+
| 565 | 12 | Tu | 2 | 1 |
+------+----+-----+------+---------+
| 565 | 12 | We | 1 | 1 |
+------+----+-----+------+---------+
| 565 | 12 | We | 2 | 0 |
+------+----+-----+------+---------+
| 565 | 12 | Th | 1 | 0 |
+------+----+-----+------+---------+
| 565 | 12 | Th | 2 | 0 |
+------+----+-----+------+---------+
| 565 | 12 | Fr | 1 | 1 |
+------+----+-----+------+---------+
| 565 | 12 | Fr | 2 | 0 |
+------+----+-----+------+---------+
| 565 | 13 | Mo | 1 | 0 |
+------+----+-----+------+---------+
| 565 | 13 | Mo | 2 | 0 |
+------+----+-----+------+---------+
| 565 | 13 | Tu | 1 | 1 |
+------+----+-----+------+---------+
| 565 | 13 | Tu | 2 | 1 |
+------+----+-----+------+---------+
| 565 | 13 | We | 1 | 1 |
+------+----+-----+------+---------+
| 565 | 13 | We | 2 | 1 |
+------+----+-----+------+---------+
| 565 | 13 | Th | 1 | 0 |
+------+----+-----+------+---------+
| 565 | 13 | Th | 2 | 0 |
+------+----+-----+------+---------+
| 565 | 13 | Fr | 1 | 0 |
+------+----+-----+------+---------+
| 565 | 13 | Fr | 2 | 0 |
+------+----+-----+------+---------+
答案 1 :(得分:1)
如果我是你,我会努力重组数据。我在生产系统中能够做到这一点的一种方法是使用重命名技巧。首先创建一个新表,然后创建一个名为原始表命名方式的视图。在根据性能要求更换现有报告和查询之前,现有报告和查询仍然有效。
与此同时,您可以使用更像幻想或加入的东西,但我总是找到一个联合解决方案,易于设置,维护并且从未遇到过性能问题。您可能会有不同的结果,但很容易测试。
编辑: 我对通过反复追加数据而创建的20,971,520行的数据集进行了一些测试(插入临时选择*来自临时)。
Select * From vTemp - 1:28
Select DtID,ID,col,Present
From Temp UnPivot (Present For Col In (Mo1,Mo2,Tu1,Tu2,We1,We2,Th1,Th2,Fr1,Fr2)) T - 1:30
Select * From vTemp Where ID = 12 - :23
Select DtID,ID,col,Present
From Temp UnPivot (Present For Col In (Mo1,Mo2,Tu1,Tu2,We1,We2,Th1,Th2,Fr1,Fr2)) T
Where ID = 12 :24
总之,如果你喜欢这个支点,那么输入就更少了。对于那些不喜欢pivot的语法的人,你可以使用Union或Union All,具体取决于你是否要删除重复项。
例如:
Drop Table Temp
Create Table Temp (DtID int, ID int, Mo1 bit, Mo2 bit, Tu1 bit, Tu2 bit, We1 bit, We2 bit, Th1 bit, Th2 bit, Fr1 bit, Fr2 bit)
Insert Temp Values ( 565 , 12 , 0 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0 )
Insert Temp Values ( 565 , 13 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 )
Insert Temp Values ( 565 , 14 , 0 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 1 , 0 )
Insert Temp Values ( 565 , 15 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 )
Insert Temp Values ( 572 , 12 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 )
Insert Temp Values ( 572 , 13 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 1 )
Insert Temp Values ( 572 , 14 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 )
Insert Temp Values ( 572 , 15 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 )
Drop View vTemp
Go
Create View vTemp As
Select DtID, ID, 'Monday' Day, 1 AmPm, Mo1 Present From Temp
Union All
Select DtID, ID, 'Monday' Day, 2 AmPm, Mo1 Present From Temp
Union All
Select DtID, ID, 'Tuesday' Day, 1 AmPm, Tu1 Present From Temp
Union All
Select DtID, ID, 'Tuesday' Day, 2 AmPm, Tu2 Present From Temp
Union All
Select DtID, ID, 'Wednesday' Day, 1 AmPm, We1 Present From Temp
Union All
Select DtID, ID, 'Wednesday' Day, 2 AmPm, We2 Present From Temp
Union All
Select DtID, ID, 'Thursday' Day, 1 AmPm, Th1 Present From Temp
Union All
Select DtID, ID, 'Thursday' Day, 2 AmPm, Th2 Present From Temp
Union All
Select DtID, ID, 'Friday' Day, 1 AmPm, Fr1 Present From Temp
Union All
Select DtID, ID, 'Friday' Day, 2 AmPm, Fr2 Present From Temp
Go
Select * From vTemp Order By ID, DtID, Day, AmPm