执行非常特定的SQL查询以不同格式放置数据时出现的问题

执行非常特定的SQL查询以不同格式放置数据时出现的问题,sql,sql-server,sql-server-2005,Sql,Sql Server,Sql Server 2005,我在处理SQL表时遇到了一些问题,需要查询该表并将其重新格式化为另一个表以用于报告目的。以下是初始表格: id int, logtimestamp datetime, serialnumber varchar(255), robotid int, amountconsumed float 机器人只有1到4个。每隔15-20分钟,就会添加新行。通常,每个机器人都会报告一个序列号,但情况并非总是如此。序列号可以周期性地具有重复项。

我在处理SQL表时遇到了一些问题,需要查询该表并将其重新格式化为另一个表以用于报告目的。以下是初始表格:

id               int, 
logtimestamp    datetime, 
serialnumber    varchar(255), 
robotid         int, 
amountconsumed  float 
机器人只有1到4个。每隔15-20分钟,就会添加新行。通常,每个机器人都会报告一个序列号,但情况并非总是如此。序列号可以周期性地具有重复项。这只在测试时发生,但也可能发生

我的目标是将给定一天内每个机器人ID的消耗量相加,并将这些值放入结果表中,如下所示:

id              int, 
logtimestamp   datetime,
robot1consumed float, 
robot2consumed float, 
robot3consumed float, 
robot4consumed float 
我很难创建一个能够准确考虑以下事实的查询:

可能存在重复的序列号 并非每个序列号都有全部4个机器人ID。如果当天不存在机器人ID,则该值应设置为0。 以下是我到目前为止提出的@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)
除了上面列出的限制之外,这种方法也可以。鉴于前面列出的约束条件,是否有建议将此查询更改为有效

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

谢谢你的快速回复。我忘了提到我正在使用MicrosoftSQL2005,而响应似乎是针对MySQL的。我在将您的解决方案重新格式化为MSSQL时遇到问题我相信第二个答案就是我要寻找的,但是,将其转换为在Microsoft SQL Server上工作是一个相当大的问题,我至今无法做到这一点。