我在数据库中有一个查询,在Agenda
表中返回6个结果,每天有可用的时间(例如:_08: 10: 00: 000 | 08: 30: 00: 000_
)和句点(例如:T(代表afternoon
}或M
代表morning
)。
我已经恢复了,但我有一个问题我无法解决。 我只能为每天的每个时段安排一个时间表。
示例:在2015-12-19
我有一个上午的时间和下午的时间,但是在2015-12-19
我早上或下午都不能有两个小时。
我的疑问是:
SELECT * FROM (
SELECT TOP(3) agendaidentificador,agendadata, 'M' AS periodo
FROM AGENDA
WHERE
agendaconsumolocktempo IS NULL
AND
agendaconsumoidentificador IS NULL
AND
agendadata > GETDATE()
GROUP BY
agendaidentificador,
agendadata
HAVING
CAST(DATEPART(HOUR,agendadata) AS INT) < 12
ORDER BY
NEWID(),
agendadata asc
) A
UNION
SELECT * FROM (
SELECT TOP(3) agendaidentificador,agendadata, 'T' AS periodo
FROM AGENDA
WHERE
agendaconsumolocktempo IS NULL
AND
agendaconsumoidentificador IS NULL
AND
agendadata > GETDATE()
GROUP BY
agendaidentificador,
agendadata
HAVING
CAST(DATEPART(HOUR,agendadata) AS INT) >= 12
AND
COUNT(CAST(agendadata AS DATE)) = 1
ORDER BY
NEWID(),
agendadata asc
) B
GROUP BY
agendaidentificador,
agendadata,
periodo
HAVING
COUNT(CAST(agendadata as DATE)) = 1
ORDER BY agendadata
结果是:
line |agendaIdentificador | agendaData | periodo
-----|--------------------|-------------------------|---------
1 | 173352 | 2015-01-12 12:50:00.000 | T
2 | 173363 | 2015-01-12 14:40:00.000 | T
3 | 175255 | 2015-01-19 11:30:00.000 | M
4 | 175520 | 2015-01-26 14:50:00.000 | T
5 | 125074 | 2015-02-25 08:20:00.000 | M
6 | 125076 | 2015-02-25 08:40:00.000 | M
行不可能发生,例如行1
和2
。
答案 0 :(得分:2)
让我们制作一些测试数据:
DECLARE @AGENDA TABLE
(
agendaIdentificador int,
agendaData datetime,
periodo varchar(1),
agendaconsumolocktempo int,
agendaconsumoidentificador int
)
INSERT INTO @AGENDA
( agendaIdentificador, agendaData, periodo, agendaconsumolocktempo, agendaconsumoidentificador )
VALUES
(173352, '2015-01-12 12:50:00.000', 'T', null, null),
(173353, '2015-01-12 12:50:00.000', 'T', null, null),
(173354, '2015-01-12 12:50:00.000', 'T', null, null),
(173355, '2015-01-12 12:50:00.000', 'T', null, null),
(173356, '2015-01-13 12:50:00.000', 'T', null, null),
(173363, '2015-01-12 14:40:00.000', 'T', null, null),
(175255, '2015-01-19 11:30:00.000', 'M', null, null),
(175520, '2015-01-26 14:50:00.000', 'T', null, null),
(125074, '2015-02-25 08:20:00.000', 'M', null, null),
(125076, '2015-02-25 08:40:00.000', 'M', null, null),
(125076, '2015-02-25 08:40:00.000', 'M', null, null),
(125076, '2015-02-25 08:40:00.000', 'M', null, null),
(125076, '2015-02-25 08:40:00.000', 'M', null, null),
(125076, '2015-02-26 08:40:00.000', 'M', null, null);
现在我修复了测试数据,将早上和下午的所有记录分开并计算出来。
WITH AGENDA AS
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY CAST(agendaData AS DATE), periodo ORDER BY agendaData) RN
FROM @AGENDA
)
现在我们接受之前的查询,但是下午会话的更改是我只想要每组的第一个(RN = 1)
SELECT * FROM (
SELECT TOP(3) agendaidentificador,agendadata, 'M' AS periodo
FROM AGENDA
WHERE agendaconsumolocktempo IS NULL
AND agendaconsumoidentificador IS NULL
AND agendadata > GETDATE()
AND DATEPART(HOUR,agendadata) < 12
AND RN = 1
GROUP BY
agendaidentificador,
agendadata
ORDER BY
NEWID(),
agendadata asc
) A
UNION
SELECT * FROM (
SELECT TOP(3) agendaidentificador,agendadata, 'T' AS periodo
FROM AGENDA
WHERE agendaconsumolocktempo IS NULL
AND agendaconsumoidentificador IS NULL
AND agendadata > GETDATE()
and RN = 1
and DATEPART(HOUR,agendadata) >= 12
GROUP BY
agendaidentificador,
agendadata
ORDER BY
NEWID(),
agendadata asc
) B
GROUP BY
agendaidentificador,
agendadata,
periodo
ORDER BY agendadata
这是输出:
agendaidentificador agendadata periodo
173352 2015-01-12 12:50:00.000 T
173356 2015-01-13 12:50:00.000 T
175255 2015-01-19 11:30:00.000 M
175520 2015-01-26 14:50:00.000 T
125074 2015-02-25 08:20:00.000 M
125076 2015-02-26 08:40:00.000 M
我添加了一些更重复的记录,清理了所有无用的条款
答案 1 :(得分:0)
您必须仅按“AgendaData”的datepart分组(最后一组)。不能按整个日期+时间字段分组。
我认为这应该有效:按TO_CHAR分组(“timestamp_field”,“YYYY-MM-DD”)
答案 2 :(得分:-1)
基于@Kevin Cook回答,我刚刚添加了其他CTE
,这解决了我的问题。
WITH CTE_AGENDA AS
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY CAST(agendaData AS DATE) ORDER BY newid(),agendaData) RN
FROM AGENDA
)
,CTE_AGENDA2 AS
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY CAST(agendaData AS DATE) ORDER BY newid(),agendaData desc) RN2
FROM AGENDA
)
SELECT * FROM (
SELECT TOP(3) agendaidentificador,agendadata, 'M' AS periodo
FROM AGENDA
WHERE
agendaconsumolocktempo IS NULL
AND
agendaconsumoidentificador IS NULL
AND
agendadata > GETDATE()
GROUP BY
agendaidentificador,
agendadata
HAVING
CAST(DATEPART(HOUR,agendadata) AS INT) < 12
ORDER BY
NEWID(),
agendadata asc
) A
UNION
SELECT * FROM (
SELECT TOP(3) agendaidentificador,agendadata, 'T' AS periodo
FROM AGENDA2
WHERE
agendaconsumolocktempo IS NULL
AND
agendaconsumoidentificador IS NULL
AND
agendadata > GETDATE()
and RN2 = 1
GROUP BY
agendaidentificador,
agendadata
HAVING
CAST(DATEPART(HOUR,agendadata) AS INT) >= 12
ORDER BY
NEWID(),
agendadata asc
) B
GROUP BY
agendaidentificador,
agendadata,
periodo
HAVING
COUNT(CAST(agendadata as DATE)) = 1
ORDER BY agendadata,periodo