SQL检查值在可变(和多个)范围内

时间:2012-12-27 14:35:17

标签: sql sql-server-2008

我有一个SQL表,包括描述一系列ID的两列;这些范围需要与第二个表中特定ID列下的单元格进行比较 - 如果它在范围内,则包含在内,第二个表格的行将包含在返回中。

编辑:可用范围受一系列用户提供的日期限制。

我只熟悉SQL的基础知识;在开始研究循环和预定义的表格函数之前,有没有人有任何建议?

SELECT * FROM [ADataBase].[dbo].[AFirstTable]
  WHERE [ALongIDNumber] <=
     (SELECT [StartOfIDRange] FROM [DHL].[dbo].[ASecondTable]
     WHERE [date] BETWEEN '2010-01-21' AND '2010-01-22')
  AND   [ALongIDNumber] >=
     (SELECT [EndOfIDRange] FROM [DHL].[dbo].[ASecondTable]
      WHERE [date] BETWEEN '2010-01-21' AND '2010-01-22')

目前,这会返回错误 Msg 512, Level 16, State 1, Line 2 Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression. 我猜测它会导致它松散,因为选择返回了几行。

我已经研究过了a similar question,其中唯一的答案是固定数量的范围。因为我在表中查询范围,所以范围的数量会发生变化。

由于此方案的性质,修改数据库是最后的手段。

感谢您的帮助!

4 个答案:

答案 0 :(得分:0)

这是一个简单的连接:

select st.*
from SecondTable st join
     FirstTable ft
     on st.id between ft.StartOfIdRange and ft.EndOfIdRange

您似乎在日期上有其他条件。你没有在问题中解释它们,所以我不确定如何将它们包含在查询中。

我仔细阅读后看到日期在第一个表格中。好吧,您可以在on子句或where子句中添加范围:

select st.*
from SecondTable st join
     FirstTable ft
     on st.id between ft.StartOfIdRange and ft.EndOfIdRange and
        ft.[date] BETWEEN '2010-01-21' AND '2010-01-22'

如果您有重叠范围,您可能需要执行distinct删除重复项:

select distinct st.*

答案 1 :(得分:0)

假设2010-01-212010-01-22分别是最短和最长日期,您可以使用MIN()MAX()函数在每个日期中获取单个ID子查询:

SELECT * 
FROM [ADataBase].[dbo].[AFirstTable]
WHERE [ALongIDNumber] BETWEEN
(
    SELECT MIN(ID)
    FROM [DHL].[dbo].[ASecondTable]
)
AND
(
    SELECT MAX(ID)
    FROM [DHL].[dbo].[ASecondTable]
)

答案 2 :(得分:0)

oracle有关键字检查范围,请按照这样的方式进行操作。关键字

之间的示例
SELECT * FROM [ADataBase].[dbo].[AFirstTable]
      WHERE [ALongIDNumber] between
         (SELECT [StartOfIDRange] FROM [DHL].[dbo].[ASecondTable]
         WHERE [date] BETWEEN '2010-01-21' AND '2010-01-22')
      AND   
         (SELECT [EndOfIDRange] FROM [DHL].[dbo].[ASecondTable]
          WHERE [date] BETWEEN '2010-01-21' AND '2010-01-22')

答案 3 :(得分:0)

我的叙述中我真的不清楚,但我认为你可能寻找的是加入的概念:

SELECT * FROM
   [ADataBase].[dbo].[AFirstTable] first
       inner join
   [DHL].[dbo].[ASecondTable] second
       on
          first.[ALongIDNumber] between second.[StartOfIDRange] and second.[EndOfIDRange]
WHERE
   second.[date] BETWEEN '20100121' AND '20100122'

这将在first中找到适合second中作为单行出现的任何ID值范围的行。这意味着,如果第二个ID值重叠,您可能会在first中的单个原始行中在结果集中收到多行。

  

在我开始研究循环之前......

别。虽然在SQL中有一些粗略的方法来执行循环,但你真的不应该去那里。 SQL背后的想法是描述你想要的结果,并且SQL引擎计算出实现它的最佳方式(无论是在幕后,循环,创建哈希表,将项目溢出到磁盘)等等。)