【问题标题】:Value2 BETWEEN (Value1 - 5) AND (Value1 + 5) [closed]Value2 BETWEEN (Value1 - 5) AND (Value1 + 5) [关闭]
【发布时间】:2015-08-17 04:29:51
【问题描述】:
SELECT *
FROM   Table1 D1 (nolock)
WHERE  1 = 1
    AND NOT EXISTS (SELECT TOP 1 *
FROM   Table2 D2 (nolock)
WHERE  d1.Account = d2.Account
    AND d2.Amount BETWEEN ( d1.Amount - 5 ) AND ( d1.Amount + 5 )
    AND Datediff(DD, d1.SALEDATE, d2.SALEDATE) BETWEEN 0 AND 60) 

我删除了很多与问题无关的功能。

本质上,我希望它在第一部分满足某些条件时查找记录(为了简单起见,我在这里使用 1=1),然后排除过去 60 天内销售的任何金额 -/ + 5 美元在同一个帐户上。

由于某种原因,它每次只返回 0 条记录,但在手动检查数据库表时,情况并非如此。我正在使用 Transact SQL。

【问题讨论】:

  • 您是否有可能将您的差异倒退? (即它应该是between -60 and 0 - 或反向d1d2
  • 对结果没有影响。我已经以这种方式使用了 Datediff 数百次,没有任何问题。这是我第一次使用 d2.Amount BETWEEN (d1.Amount - 5) AND (d1.Amount + 5) 的表达式。
  • 没问题。只是在黑暗中刺伤。你能给我们一个示例数据集吗?
  • 我无法提供来自机密来源的数据。我什至不得不更改字段/列的名称以保护源的隐私等。我完全被难住了为什么这不起作用..我更像是程序员而不是 DBA,所以我想也许我是试图做一些在编程上很好但在 SQL 中的 SELECT 语句的上下文中根本不起作用的事情..
  • 好的,解决了...这么简单...我忘了从 D1 中排除结果。所以现在它有一个 d2.indexkey d1.indexkey 语句,一切正常......哈哈

标签: sql sql-server tsql between


【解决方案1】:

好的,解决了...这么简单...我忘了从 D1 中排除结果。所以现在它有一个 d2.indexkey d1.indexkey 语句并且一切正常......哈哈

【讨论】:

  • 绝对不会从您简化的示例中注意到这一点,特别是如果它实际上是一个自联接。 (问题中有两个 不同的 表)。很高兴你解决了它。
  • 是的,对不起。这是我第一次在这里发帖,我试图隐藏事物的机密工作原理。在处理机密流程和数据时很难向人们提问:(
【解决方案2】:

最好使用临时表进行自连接或子查询,虽然你的数据库处理率会降低,你会得到更快的结果。

SELECT * into #temp
FROM   Table1 D1


select * from #temp t1
WHERE  t1.id not in(
    SELECT t2.id
        FROM    #temp t2
    WHERE  t1.Account = t2.Account
        AND t2.Amount BETWEEN ( t1.Amount - 5 ) AND ( t1.Amount + 5 )
        AND Datediff(DD, t1.SALEDATE, t2.SALEDATE) BETWEEN 0 AND 60) 

但是,这只是您查询的替代方法。

临时表的优点

  • 表“存在”——也就是说,它被物化为一个表,至少在内存中,它包含结果集并且可以重用。

  • 在某些情况下,当您必须对数据执行一些复杂的转换时,可以提高性能或减少阻塞 - 例如,如果您想从基表中获取一组“快照”很忙,然后对该集合进行一些复杂的计算,如果您将行从基表中取出并尽快解锁,然后独立完成工作,则可以减少争用。在某些情况下,相对于并发优势而言,真实临时表的开销很小。

  • 临时表虽然在 tempDB 数据库中分配了空间,但通常只能从内存中访问,除非服务器处于内存压力下,或者表中的数据量很大。

【讨论】:

  • 使用临时表/物理表是否会对性能产生任何影响?你能解释一下或提供一些参考吗?
  • 添加了一些为什么我们更喜欢临时表的好处。
  • ... 和内联表通常也可以从内存中访问。如果内联表最终在内存中,它们也将被重用。您的建议是将 every 列加载到临时表中比使用 EXISTS 更快(它足够聪明,只能访问页面中所需的最少数据)
  • 非常感谢您提出关于#temp 表的想法。它使我能够为子查询创建一个更小、更相关的数据集,从而使查询速度提高了许多数量级。所以现在我有: SELECT * INTO #Temp from Table1 WHERE SaleDate > '20150101' AND CompanyKey = 123 GO 开头。然后在子查询中,我在#temp 表上进行选择。这些表都是半夜刷新的静态数据,这样使用没有问题。再次感谢。
猜你喜欢
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多