【问题标题】:Grouping OR clause with DATEDIFFS in SQL在 SQL 中使用 DATEDIFFS 对 OR 子句进行分组
【发布时间】:2011-08-18 20:28:09
【问题描述】:

我有一个 sql 表。我们将其称为“表”。我正在尝试使用一些 WHERE 子句进行选择。我需要最后一个 where 子句是 OR。通常,我只是这样做:

SELECT *
FROM table
WHERE 1=1
AND (firstName='tom' OR lastName='jones')

但是,在此特定查询中,我需要 OR 的两侧为 DATEDIFFS。我正在尝试获取时间戳和“NOW”之间的差异大于 10 小时或小于 0 小时的所有行。所以,我现在得到的错误是:

SELECT *
FROM table
WHERE 1=1
AND (
      DATEDIFF(hh, table.timestamp, GETDATE()) > 10
    OR
      DATEDIFF(hh, table.timestamp, GETDATE()) < 0
    )

我已经尝试了上面的几个不同版本,但似乎没有任何效果。任何帮助将非常感激!我确定我只是盯着它看太久了,这很愚蠢。

一个新的更详细的查询:

是的,我的查询中有两个左连接,这可能是这里有所作为的原因。我试图让我的例子简单,但它最终咬了我。这是一个更相关的查询:

SELECT
  tblCheckoutActivity.rid,  
  tblCheckoutActivity.checkedOutUser,
  tblCheckoutActivity.checkedOutTime,
  tblCheckoutInventory.serial,
  tblCheckoutInventory.unit,
  tblCheckoutInventory.tag,
  tblCheckoutUsers.firstName,
  tblCheckoutUsers.lastName
FROM
  tblCheckoutActivity
LEFT JOIN
  tblCheckoutInventory
ON 
  tblCheckoutActivity.scannerID = tblCheckoutInventory.SID
LEFT JOIN
  tblCheckoutUsers
ON
  tblCheckoutActivity.checkedOutUser = tblCheckoutUsers.badgeID
WHERE
  tblCheckoutActivity.checkedInTime Is Null 
AND 
  tblCheckoutInventory.site='San Francisco'
AND
  (
    DATEDIFF(hh, tblCheckoutActivity.checkedOutTime, GETDATE()) > 10
  OR
    DATEDIFF(hh, tblChecckoutActivity.checkedOutTime, GETDATE()) < 0
  )
ORDER BY tblCheckoutUsers.lastName 

【问题讨论】:

  • 根据所有的 cmets,我将我的钱放在括号中的不匹配上。您能否快速计算一下您的查询中有多少个 ('s 和 )。
  • 此表名中的错字 - tblChecckoutActivity
  • @slothrop - 该死的......我现在觉得自己像个白痴。
  • @Dex 嗯嗯,下一次的一个很好的教训是发布一个实际重现问题的查询:)
  • @Dex: 将DATEDIFF(hh, tblCheckoutActivity.checkedOutTime, GETDATE()) &gt; 10 重写为tblCheckoutActivity.checkedOutTime &lt; DATEADD(hh,10,GETDATE()) 这样的索引checkedOutTime 可以使用。

标签: sql sql-server where datediff


【解决方案1】:

我认为您的问题出在其他地方。我刚刚运行,没有错误:

with temp as
(
select 1 as id,        CAST('10/31/2011' as DATETIME) as timestamp
UNION
SELECT 2,        CAST('11/1/2011' as DATETIME)
UNION
SELECT 3,        CAST('11/2/2011' as DATETIME)
UNION
SELECT 4,        CAST('11/3/2011' as DATETIME)
UNION
SELECT 5,        CAST('11/6/2011' as DATETIME)
UNION
SELECT 6,        CAST('11/8/2011' as DATETIME)
)

SELECT *
FROM temp
WHERE 1=1
AND (
      DATEDIFF(hh, timestamp, GETDATE()) > 10
    OR
      DATEDIFF(hh, timestamp, GETDATE()) < 0
    )

您是否向我们展示了您的查询的缩写版本?您的示例中是否缺少此查询之前的代码?

【讨论】:

  • 是的...有两个左连接和另一个表。我确信这就是发生并发症的地方。但是,如果没有我的 DATEDIFF OR 子句,查询运行良好。
  • 嗨 Abe - 我是 CTE 的新手。一般来说,通过WITH 子句使用 CTE 与简单地创建和使用临时表之间的主要区别是什么?
【解决方案2】:

如果您使用的是时间戳数据类型,那就是您的问题。您不能在 DATETIME 和时间戳之间进行 DATEDIFF 比较。

【讨论】:

    【解决方案3】:
    SELECT *
    FROM table
    WHERE 
          DATEDIFF(hh, table.timestamp, GETDATE()) > 10
    UNION
    SELECT *
    FROM table
    WHERE 
          DATEDIFF(hh, table.timestamp, GETDATE()) < 0
    

    又快又脏,但它应该可以工作

    【讨论】:

    • 为了性能,我不能像这样对相同的数据运行两个选择。我很欣赏你的建议,但它不适用于我的情况。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 2011-08-23
    • 2010-11-13
    • 1970-01-01
    • 2014-07-25
    • 1970-01-01
    相关资源
    最近更新 更多