【问题标题】:Tricky If Exists SQL query needed to check overlapped valuesTricky If Exists SQL 查询需要检查重叠值
【发布时间】:2009-12-11 06:23:22
【问题描述】:

我在 SQL Server 中有一个存储 MINIMUM_AMOUNT、MAXIMUM_AMOUNT 和 CURRENCY_ID 的表。现在我想构建一个 SQL 查询,它将检查要插入的新值是否已经存在于表中。例如:我的表有 2 条记录如下

RANGE_ID   MINIMUM_AMOUNT     MAXIMUM_AMOUNT    CURRENCY_ID
------------------------------------------------------------
 1         3000                 9000                3
 2         12000                17000               3

现在当用户插入一条新记录时,它不应该在已经可用的值之间

ie : 用户不能输入这些值对

  1 ) Min Amount : 4000  , Max Amount : 5000 ,Currency Id : 3
        because this range already lies in the first record (RANGE_ID 1)
  2)  Min Amount : 8000 , Max Amount : 10000,Currency d : 3
        because the minimum amount is already present in the range specified in first record (3000-9000)
  3)   Min Amount : 8000, Max Amount : 15000 , currency Id=3
       because the minimum amount is already present in one range and the maximum amount is also present in another range
  4)   Min Amount : 2500 , Max Amount : 11000 ,Currency Id=3
        because the this range overlaps with the data in first record

用户应该能够使用不同的货币 ID 输入上述范围。

我正在寻找一个 If Exists 查询来检查这个。

【问题讨论】:

    标签: sql exists


    【解决方案1】:

    看看这个

    DECLARE @Table TABLE(
            RANGE_ID INT,
            MINIMUM_AMOUNT FLOAT,
            MAXIMUM_AMOUNT FLOAT,
            CURRENCY_ID INT
    )
    
    INSERT INTO @Table (RANGE_ID,MINIMUM_AMOUNT,MAXIMUM_AMOUNT,CURRENCY_ID) SELECT 1,3000,9000,3
    INSERT INTO @Table (RANGE_ID,MINIMUM_AMOUNT,MAXIMUM_AMOUNT,CURRENCY_ID) SELECT 2,12000,17000,3
    
    DECLARE @NewMin FLOAT,
            @NewMax FLOAT,
            @CurrencyID INT
    
    SELECT  @NewMin = 4000,
            @NewMax = 5000,
            @CurrencyID = 3
    
    SELECT  *
    FROM    @Table
    WHERE   CURRENCY_ID = @CurrencyID
    AND     NOT (MINIMUM_AMOUNT > @NewMax OR MAXIMUM_AMOUNT < @NewMin)  
    

    这是检查的反面

    • 完全重叠
    • 部分重叠
    • 内部重叠

    【讨论】:

      【解决方案2】:

      我认为这样做可以:

      IF EXISTS
      (
          SELECT *
          FROM MinMaxTable mmt
          WHERE (mmt.CURRENCY_ID = @currencyID) AND
                (@minAmount BETWEEN mmt.MINIMUM_AMOUNT AND mmt.MAXIMUM_AMOUNT) AND
                (@maxAmount BETWEEN mmt.MINIMUM_AMOUNT AND mmt.MAXIMUM_AMOUNT)
      )
      BEGIN
          /* New data is within an existing range. */
      END
      ELSE
      BEGIN
          /* Partially or completely outside an existing range. */
      END;
      

      使用IF NOT EXISTS 反转条件。

      【讨论】:

      • 这不处理重叠
      【解决方案3】:
      select 1 
      from currency_ranges R
      where R.CURRENCY_ID = :newCurrency
      and (
      (R.MINIMUM_AMOUNT <= :newMin and R.MAXIMUM_AMOUNT >= :newMin)
      or (R.MINIMUM_AMOUNT <= :newMax and R.MAXIMUM_AMOUNT >= :newMax)
      )
      

      这可以用作 EXISTS 语句来检查范围内的重叠

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-14
        • 2017-11-04
        • 1970-01-01
        相关资源
        最近更新 更多