我在处理需要查询并重新格式化为另一个表的SQL表时出于报告目的而遇到一些麻烦。这是初始表:
id int,
logtimestamp datetime,
serialnumber varchar(255),
robotid int,
amountconsumed float
robotid
仅为1到4.每隔15-20分钟,会添加新行。通常,每个机器人都会报告一个序列号,但情况并非总是如此。序列号可以定期重复。 (这只在测试时发生,但可能会发生。)
我的目标是在给定的一天中计算每个robotid的消耗量,并将这些值放在一个如下所示的结果表中:
id int,
logtimestamp datetime,
robot1consumed float,
robot2consumed float,
robot3consumed float,
robot4consumed float
我无法创建一个能够准确考虑
事实的查询这是我到目前为止所提出的(@startDate和@endDates):
SELECT
timestamp=dateadd(month,((Year(R1.logtimestamp)-1900)*12)+Month(R1.logtimestamp)-1,Day(R1.logtimestamp)-1),
sum(R1.robot1consumed ),
sum(R2.robot1consumed ),
sum(R3.robot1consumed ),
sum(R4.robot1consumed )
FROM
Robot_Consumption R1,
Robot_Consumption R2,
Robot_Consumption R3,
Robot_Consumption R4
WHERE
R1.robotid = '1'
AND R2.robotid = '2'
AND R3.robotid = '3'
AND R4.robotid = '4'
AND R1.logtimestamp BETWEEN @startDate AND @endDate
AND R1.serialnumber = R2.serialnumber
AND R1.serialnumber = R3.serialnumber
AND R1.serialnumber = R4.serialnumber
GROUP BY
Year(R1.logtimestamp), Month(R1.logtimestamp), Day(R1.logtimestamp)
除了上面列出的限制,这个工作正常。是否有任何建议在给定先前列出的约束条件的情况下将此查询更改为有效?
答案 0 :(得分:2)
SELECT '0000-00-00' + INTERVAL dte DAY AS robot_date,
id,
SUM(amountconsumed)
FROM (
SELECT 1 AS id
UNION ALL
SELECT 2
UNION ALL
SELECT 3
UNION ALL
SELECT 4
) r
-- this is to select all robotids
JOIN
(
SELECT DISTINCT TO_DAYS(logtimestamp) AS dte
FROM Robot_Consumption
WHERE logtimestamp BETWEEN @startDate AND @endDate
) rd
-- this is to select all days that have any records
LEFT OUTER JOIN
RobotConsumption rc
ON rc.robotid = r.id
AND rc.logtimestamp BETWEEN '0000-00-00' + INTERVAL dte DAY AND '0000-00-00' + INTERVAL dte + 1 DAY
WHERE NOT EXISTS
(
SELECT 1
FROM Robot_Consumption rci
WHERE rci.robotid = rc.robotid
AND rci.serial_number = rc.serial_number
AND rci.id < rc.id
)
-- this is to handle duplicates
GROUP BY
dte, id
如果您需要连续拍摄结果,请使用:
SELECT '0000-00-00' + INTERVAL dte DAY AS robot_date,
COALESCE(
(
SELECT SUM(amountconsumed)
FROM Robot_Consumption rc
WHERE rc.robotid = 1
AND rc.logtimestamp BETWEEN '0000-00-00' + INTERVAL dte DAY AND '0000-00-00' + INTERVAL dte + 1 DAY
AND NOT EXISTS
(
SELECT 1
FROM Robot_Consumption rci
WHERE rci.robotid = rc.robotid
AND rci.serial_number = rc.serial_number
AND rci.id < rc.id
)
), 0) AS robot1consumed,
COALESCE(
(
SELECT SUM(amountconsumed)
FROM Robot_Consumption rc
WHERE rc.robotid = 2
AND rc.logtimestamp BETWEEN '0000-00-00' + INTERVAL dte DAY AND '0000-00-00' + INTERVAL dte + 1 DAY
AND NOT EXISTS
(
SELECT 1
FROM Robot_Consumption rci
WHERE rci.robotid = rc.robotid
AND rci.serial_number = rc.serial_number
AND rci.id < rc.id
)
), 0) AS robot2consumed,
COALESCE(
(
SELECT SUM(amountconsumed)
FROM Robot_Consumption rc
WHERE rc.robotid = 3
AND rc.logtimestamp BETWEEN '0000-00-00' + INTERVAL dte DAY AND '0000-00-00' + INTERVAL dte + 1 DAY
AND NOT EXISTS
(
SELECT 1
FROM Robot_Consumption rci
WHERE rci.robotid = rc.robotid
AND rci.serial_number = rc.serial_number
AND rci.id < rc.id
)
), 0) AS robot3consumed,
COALESCE(
(
SELECT SUM(amountconsumed)
FROM Robot_Consumption rc
WHERE rc.robotid = 4
AND rc.logtimestamp BETWEEN '0000-00-00' + INTERVAL dte DAY AND '0000-00-00' + INTERVAL dte + 1 DAY
AND NOT EXISTS
(
SELECT 1
FROM Robot_Consumption rci
WHERE rci.robotid = rc.robotid
AND rci.serial_number = rc.serial_number
AND rci.id < rc.id
)
), 0) AS robot4consumed,
FROM (
SELECT DISTINCT TO_DAYS(logtimestamp) AS dte
FROM Robot_Consumption
WHERE logtimestamp BETWEEN @startDate AND @endDate
) rd