sqlserver数据库 sql查询难题

Kings_cool 2020-04-29 01:02:18
数据库中考勤表A_t的结构:
id name time 后略。。。
1 张三 2020-04-01 08:00:00
1 张三 2020-04-01 12:00:00
1 张三 2020-04-01 14:00:00
1 张三 2020-04-01 18:00:00
1 张三 2020-04-02 08:00:00
。。。
2 李四 2020-04-01 08:02:52
。。。
现在需要通过sql查询并得到下列格式:
id name date 上午/下午 judge
1 张三 2020-04-01 上午 4
1 张三 2020-04-01 下午 4
2 李四 2020-04-01 上午 0

注: 第一、二行的08:00:0-12:00:00将被表示为表2中的 上午,4 (注存在微小误差如12:01:00也判定为4)
同理下午的 14:00-18:00 也将判定为 下午,4

我知道日期转换函数,
但是我不知道怎么让 2行数据变成1行数据的方法。(以题中的逻辑)
...全文
168 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Kings_cool 2020-04-30
  • 打赏
  • 举报
回复
引用 6 楼 XXXXn帅气 的回复:
[quote=引用 2 楼 Hello World, 的回复:] 所谓两行变一行:
DECLARE @t TABLE(id INT NOT NULL, [name] NVARCHAR(10) NOT NULL, [time] DATETIME NOT NULL)
INSERT @t(id, [name], [time])
VALUES(1,'张三','2020-04-01 08:00:00'),(1,'张三','2020-04-01 12:00:00'),
(1,'张三','2020-04-01 14:00:00'),(1,'张三','2020-04-01 18:00:00'),(1,'张三','2020-04-02 08:00:00');

WITH datas AS (SELECT   *, ROW_NUMBER() OVER (PARTITION BY [id] ORDER BY [time]) AS seq FROM  @t)
SELECT  a.id,
        a.[name],
        a.[time] beginTime,
        b.endTime
FROM    datas a
        OUTER APPLY(SELECT  b.time AS endTime
                    FROM    datas b
                    WHERE   a.id = b.id AND a.seq = b.seq - 1) b
WHERE   a.seq % 2 = 1;
后面的计算就简单了吧
DECLARE @t TABLE(id INT NOT NULL, [name] NVARCHAR(10) NOT NULL, [time] DATETIME NOT NULL)
INSERT @t(id, [name], [time])
VALUES(1,'张三','2020-04-01 08:00:00'),(1,'张三','2020-04-01 12:00:00'),
(1,'张三','2020-04-01 14:00:00'),(1,'张三','2020-04-01 18:00:00'),(1,'张三','2020-04-02 08:00:00'),(1,'张三','2020-04-03 08:00:00');
 
WITH datas AS (SELECT   *, ROW_NUMBER() OVER (PARTITION BY id,convert(nvarchar(10),time,20) ORDER BY [time]) AS seq FROM  @t)
SELECT  a.id,
        a.[name],
        a.[time] beginTime,
        b.endTime
FROM    datas a
        OUTER APPLY(SELECT  b.time AS endTime
                    FROM    datas b
                    WHERE   a.id = b.id AND a.seq = b.seq - 1 and DATEDIFF(DAY,b.time,a.time)<1) b
WHERE   a.seq % 2 = 1;
参考大佬的思路 优化下逻辑 [/quote] good 感谢你们提供的答案
XXXXn帅气 2020-04-30
  • 打赏
  • 举报
回复
引用 2 楼 Hello World, 的回复:
所谓两行变一行:

DECLARE @t TABLE(id INT NOT NULL, [name] NVARCHAR(10) NOT NULL, [time] DATETIME NOT NULL)
INSERT @t(id, [name], [time])
VALUES(1,'张三','2020-04-01 08:00:00'),(1,'张三','2020-04-01 12:00:00'),
(1,'张三','2020-04-01 14:00:00'),(1,'张三','2020-04-01 18:00:00'),(1,'张三','2020-04-02 08:00:00');

WITH datas AS (SELECT *, ROW_NUMBER() OVER (PARTITION BY [id] ORDER BY [time]) AS seq FROM @t)
SELECT a.id,
a.[name],
a.[time] beginTime,
b.endTime
FROM datas a
OUTER APPLY(SELECT b.time AS endTime
FROM datas b
WHERE a.id = b.id AND a.seq = b.seq - 1) b
WHERE a.seq % 2 = 1;


后面的计算就简单了吧

DECLARE @t TABLE(id INT NOT NULL, [name] NVARCHAR(10) NOT NULL, [time] DATETIME NOT NULL)
INSERT @t(id, [name], [time])
VALUES(1,'张三','2020-04-01 08:00:00'),(1,'张三','2020-04-01 12:00:00'),
(1,'张三','2020-04-01 14:00:00'),(1,'张三','2020-04-01 18:00:00'),(1,'张三','2020-04-02 08:00:00'),(1,'张三','2020-04-03 08:00:00');

WITH datas AS (SELECT *, ROW_NUMBER() OVER (PARTITION BY id,convert(nvarchar(10),time,20) ORDER BY [time]) AS seq FROM @t)
SELECT a.id,
a.[name],
a.[time] beginTime,
b.endTime
FROM datas a
OUTER APPLY(SELECT b.time AS endTime
FROM datas b
WHERE a.id = b.id AND a.seq = b.seq - 1 and DATEDIFF(DAY,b.time,a.time)<1) b
WHERE a.seq % 2 = 1;

参考大佬的思路 优化下逻辑

Kings_cool 2020-04-29
  • 打赏
  • 举报
回复
引用 2 楼 Hello World, 的回复:
所谓两行变一行:
DECLARE @t TABLE(id INT NOT NULL, [name] NVARCHAR(10) NOT NULL, [time] DATETIME NOT NULL)
INSERT @t(id, [name], [time])
VALUES(1,'张三','2020-04-01 08:00:00'),(1,'张三','2020-04-01 12:00:00'),
(1,'张三','2020-04-01 14:00:00'),(1,'张三','2020-04-01 18:00:00'),(1,'张三','2020-04-02 08:00:00');

WITH datas AS (SELECT   *, ROW_NUMBER() OVER (PARTITION BY [id] ORDER BY [time]) AS seq FROM  @t)
SELECT  a.id,
        a.[name],
        a.[time] beginTime,
        b.endTime
FROM    datas a
        OUTER APPLY(SELECT  b.time AS endTime
                    FROM    datas b
                    WHERE   a.id = b.id AND a.seq = b.seq - 1) b
WHERE   a.seq % 2 = 1;
后面的计算就简单了吧
感谢解答,我研究一下
Kings_cool 2020-04-29
  • 打赏
  • 举报
回复
引用 1 楼 nebuung 的回复:
看不懂你的注,如你所说 8:00-12:00是上午,4 12:01 也是 4(应该是下午,4?) 14:00-18:00 是下午,4 问题1:什么情况下judge是0,还有其他数字没有 2:条件就是条件,系统逻辑没有什么微小误差(比如你需要设置8:00-12:05是上午,4 。5分钟是你说的误差,但一定要到条件里面去) 3:12:00-14:00 judge是什么,18:00-8:00judge又是什么
然后关于 上午0 意思是上午数据为奇数行则为0,仅当偶数行时可能为4
Kings_cool 2020-04-29
  • 打赏
  • 举报
回复
引用 1 楼 nebuung 的回复:
看不懂你的注,如你所说 8:00-12:00是上午,4 12:01 也是 4(应该是下午,4?) 14:00-18:00 是下午,4 问题1:什么情况下judge是0,还有其他数字没有 2:条件就是条件,系统逻辑没有什么微小误差(比如你需要设置8:00-12:05是上午,4 。5分钟是你说的误差,但一定要到条件里面去) 3:12:00-14:00 judge是什么,18:00-8:00judge又是什么
你好,其实就是个考勤的计算, 12:00是理想数据,实际上都是12:02,12:05那样,我可以设置误差调节这个,这不是关键,主要是2行数据变1行这个逻辑我不会实现
Hello World, 2020-04-29
  • 打赏
  • 举报
回复
所谓两行变一行:

DECLARE @t TABLE(id INT NOT NULL, [name] NVARCHAR(10) NOT NULL, [time] DATETIME NOT NULL)
INSERT @t(id, [name], [time])
VALUES(1,'张三','2020-04-01 08:00:00'),(1,'张三','2020-04-01 12:00:00'),
(1,'张三','2020-04-01 14:00:00'),(1,'张三','2020-04-01 18:00:00'),(1,'张三','2020-04-02 08:00:00');

WITH datas AS (SELECT *, ROW_NUMBER() OVER (PARTITION BY [id] ORDER BY [time]) AS seq FROM @t)
SELECT a.id,
a.[name],
a.[time] beginTime,
b.endTime
FROM datas a
OUTER APPLY(SELECT b.time AS endTime
FROM datas b
WHERE a.id = b.id AND a.seq = b.seq - 1) b
WHERE a.seq % 2 = 1;


后面的计算就简单了吧
nebuung 2020-04-29
  • 打赏
  • 举报
回复
看不懂你的注,如你所说 8:00-12:00是上午,4
12:01 也是 4(应该是下午,4?)
14:00-18:00 是下午,4
问题1:什么情况下judge是0,还有其他数字没有
2:条件就是条件,系统逻辑没有什么微小误差(比如你需要设置8:00-12:05是上午,4 。5分钟是你说的误差,但一定要到条件里面去)
3:12:00-14:00 judge是什么,18:00-8:00judge又是什么


34,837

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧