Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 查询笨拙存储的数据_Sql_Sql Server_Tsql - Fatal编程技术网

Sql 查询笨拙存储的数据

Sql 查询笨拙存储的数据,sql,sql-server,tsql,Sql,Sql Server,Tsql,为这个模糊的标题道歉,但这与其说是寻求直接答案,不如说是寻求建议。作为参考,我使用SSMS 2014 我正在处理一个我没有创建的数据库,我正在努力处理当前格式的数据。我已经包括了下表的一个例子 +-----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ |DtID | ID | Mo1 | Mo2 | Tu1 | Tu2 | We1 | We2 | Th1 | Th2 | Fr1 | Fr2 | +-----+

为这个模糊的标题道歉,但这与其说是寻求直接答案,不如说是寻求建议。作为参考,我使用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行为例)

这可能吗?是否有一种有效的方法来查询数据?我对SQL相当陌生,到目前为止,我几乎所有的学习都来自于在这个网站上解释问题和答案。正如我所说,我真的不知道我所寻找的答案,所以这里的用户的集体建议和智慧对我非常有用


非常感谢。

我想你不会想泄露当天的信息的

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


如果我是你,我会努力重组数据。我能够在生产系统中做到这一点的一种方法是使用重命名技巧。首先创建一个新表,然后按照原始表的命名方式创建一个名为的视图。现有报告和查询在根据性能要求进行替换之前仍然有效

与此同时,您可以使用更奇特的东西,如unpivot或join,但我始终发现联合解决方案易于设置、维护,而且从未出现性能问题。您可能有不同的结果,但它很容易测试

编辑: 我在一个20971520行的数据集上运行了一些测试,该数据集是通过反复添加数据创建的(Insert Temp Select*From Temp)

总之,如果您喜欢pivot,那么它的键入量就要少得多。对于那些不喜欢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

你说得对。第二种表述比第一种表述更有意义。我认为现有的桌子设计是有缺陷的,但是我们必须利用现有的桌子。有许多方法可以使它成为所需的形式。您可以交叉连接到另一个表,将1行转换为10行(这是您想要的)-下面是一个示例:。你可以使用十<代码>联合所有的< /COD>。但是一般来说,查询规划者是很难优化的。虽然工作量很大,但是如果数据库设计始终是“笨拙的”,并且你必须做大量的报告,你可以建立一个数据仓库,我也会考虑第二个设计缺陷。因为它实际上不代表工作日。由于没有其他标准可供排序,因此无法判断第二个表格中的一行是指哪一天。谢谢你的评论,尼克。我已经记下了这一点,将来在类似情况下一定会参考!他说的是询问而不是DML。我不知道如何用他想要的方式表示数据,并且能够在不改变我强烈推荐的基本设计的情况下进行插入。这是性能测试吗?(1) 你重复了多少次?(2) 每次运行前是否已清理/填充缓存?(3) 你花了服务器时间还是客户端时间?将
select*
更改为
select count(*)
怎么样?这只是出于我的目的,我可以用它来找到我的解决方案。如果您注意到我的“首选”选项,则日期信息不会因此丢失,因为日期标识基于日期递增。例如,星期二用566表示。我没有得到“首选”partBy preferred,我指的是原始帖子中的表格,我觉得使用它更舒服。我的数据集的实际列标题称为“RegIdentAM1”、“RegIdentAM2”等,在本例中,我将其称为“MoAM”、“TuAM”等。我刚刚使用了正确的函数来提取一个日期标识符,并将其添加到日期标识符中,然后减去一个返回正确日期的标识符。非常高兴您的回复-我以前从未遇到过unpivot,因此我很高兴现在可以使用它。
+------+----+-----+------+---------+
| 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       |
+------+----+-----+------+---------+
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
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