SQL语句没有完全按照我的意愿去做

时间:2014-07-22 15:14:05

标签: php sql sql-server

我目前正在SQL Server Management Studio中编写一个将在PHP中使用的SQL查询

该查询旨在获取昨天上午8点到晚上8点之间的所有记录,并计算有多少记录fffffff0CardID当前这只记录了列中的355条记录CardCOUNT只是他们中的第一名并不是我想要的,我应该怎么做?

SELECT 
   COUNT(CardID) AS CardCOUNT,
   ReaderTime,
   controllerID,
   dtReading
FROM 
   myMachineMonitor2.dbo.ReaderData
WHERE 
   (controllerID = 31)
   AND (ReaderTime BETWEEN '08:00:00' AND '20:00:00')
   AND (CardID = 'fffffff0')
   AND (DATEDIFF(DAY, DATEADD(DAY, - 1, CURRENT_TIMESTAMP), dtReading) = 0)
GROUP BY 
   ReaderTime, controllerID, dtReading 

在玩完之后我有点想出来就是我想出来的

SELECT 
    COUNT(CardID) AS CardCOUNT
FROM 
    myMachineMonitor2.dbo.ReaderData
WHERE 
    (controllerID = 31)
    AND (ReaderTime BETWEEN '08:00:00' AND '20:00:00')
    AND (CardID = 'fffffff0')
    AND (DATEDIFF(DAY, DATEADD(DAY, - 0, CURRENT_TIMESTAMP), dtReading) = 0)

3 个答案:

答案 0 :(得分:1)

这会将逻辑更改为仅使用当前日期:

SELECT COUNT(CardID) AS CardCOUNT, ReaderTime, controllerID, dtReading
FROM myMachineMonitor2.dbo.ReaderData
WHERE (controllerID = 31) AND
      (CardID = 'fffffff0') AND
      dtReading >= cast(cast(getdate() as date) as datetime) - 16.0/24 and
      dtReading >= cast(cast(getdate() as date) as datetime) - 4.0/24
GROUP BY ReaderTime, controllerID, dtReading ;

施放到date会将值置于午夜。然后它减去16和4小时的范围。

此表达式也可以完成当前日期的所有工作。

答案 1 :(得分:1)

我知道有关于datetime列的sargability的一些争论,但我会更像这样。通过分离这两个条件,我发现这更容易理解。

SELECT COUNT(CardID) AS CardCOUNT
    , ReaderTime
    , controllerID
    , dtReading
FROM myMachineMonitor2.dbo.ReaderData
WHERE controllerID = 31
    AND CardID = 'fffffff0' 
    AND ReaderTime >= dateadd(hour, 8, dateadd(day, datediff(day, 0, CURRENT_TIMESTAMP) - 1, 0)) --8am yesterday
    AND ReaderTime < dateadd(hour, 19, dateadd(day, datediff(day, 0, CURRENT_TIMESTAMP) - 1, 0)) --9pm yesterday
GROUP BY ReaderTime
    , controllerID
    , dtReading;

答案 2 :(得分:1)

问题在于时间是一个分组条件,你在每个不同的时间强制一行,不允许在一段时间内聚合。只需从你的GROUP BY中抽出时间,你就可以了。

SELECT controllerID, COUNT(CardID) AS CardCOUNT
FROM myMachineMonitor2.dbo.ReaderData
WHERE (controllerID = 31)
  AND (ReaderTime BETWEEN '08:00:00' AND '20:00:00')
  AND (CardID = 'fffffff0')
  AND (DATEDIFF(DAY, DATEADD(DAY, - 1, CURRENT_TIMESTAMP), dtReading) = 0)
GROUP BY controllerID