簡體   English   中英

SQL 查詢邊界范圍內的記錄和范圍外的max/min

[英]SQL query records within a range of boundaries and max/min outside the range

我有以下三個簡單的 T-SQL 查詢。 第一個是獲取一定范圍內的記錄(DATETIME 類型):

 SELECT value, timestamp 
 FROM myTable
 WHERE timestamp BETWEEN @startDT AND @endDT

第二個是獲取最接近@startDT 的記錄(DATETIME 類型)

 SELECT TOP 1
   value, timestamp
 FROM myTable
 WHERE timestamp > @startDT
 ORDER BY timestamp DESC

最后一個是在@endDT之后獲得最近的記錄:

 SELECT TOP 1
   value, timestamp
 FROM myTable
 WHERE timestamp < @endDT
 ORDER BY timestamp ASC

我想將以上三個查詢的所有記錄作為一組記錄。 我嘗試使用 UNION,但似乎 UNION 中的子查詢不允許使用 ORDER BY 子句。 有沒有有效的方法來獲得我的結果?

 . .  * | * * * * * | * . . .
      start        end

上圖只是簡單的將*s的記錄顯示為我需要的記錄,而|...| 是界限。

順便說一句,myTable 中的數據量很大。 我的理解 UNION 不是從 UNION 獲取數據的有效方法。 沒有UNION獲取數據的任何有效方法?

如你所願,沒有 UNION。

MySQL (已測試)

SELECT 
     dv1.timestamp, dv1.values
FROM 
     myTable AS dv1
WHERE 
    dv1.timestamp 
    BETWEEN (
           SELECT dv2.timestamp 
           FROM myTable AS dv2
           WHERE dv2.timestamp < '@START_DATE' 
           ORDER BY dv2.timestamp DESC 
           LIMIT 1
           )
    AND ( SELECT dv3.timestamp 
          FROM myTable AS dv3
          WHERE dv3.timestamp > '@END_DATE' 
          ORDER BY dv3.timestamp ASC 
          LIMIT 1
        )

編輯對不起,我忘了注意 T-SQL。

T-SQL(未測試

SELECT 
     dv1.timestamp, dv1.values
FROM 
     myTable AS dv1
WHERE 
    dv1.timestamp 
    BETWEEN (
           SELECT TOP 1 dv2.timestamp 
           FROM myTable AS dv2
           WHERE dv2.timestamp >  @START_DATE 
           ORDER BY dv2.timestamp DESC
           )
    AND ( SELECT TOP 1 dv3.timestamp 
          FROM myTable AS dv3
          WHERE dv3.timestamp <  @END_DATE 
          ORDER BY dv3.timestamp ASC
        )

注意如果結果不正確,您可以只交換子查詢(即運算符和 ASC/DESC)。

打破常規思考問題:)

你可以使用 max/min 來獲得你需要的值。 Order by + top 1排序不是獲得最大值的最佳方式,我可以在您的查詢中看到。 要對 n 個項目進行排序,其 O(n 到 2 次方),得到最大值應該只有 O(n)

SELECT value, timestamp 
 FROM myTable
 WHERE timestamp BETWEEN @startDT AND @endDT
union
select A.Value, A.TimeStamp
From (
 SELECT TOP 1
   value, timestamp
 FROM myTable
 WHERE timestamp > @startDT
 ORDER BY value, timestamp DESC ) A
Union
Select A.Value, A.TimeStamp
From (
 SELECT TOP 1
   value, timestamp
 FROM myTable
 WHERE timestamp < @endDT
 ORDER BY value, timestamp ASC ) A

您帖子中的第二個和第三個查詢沒有多大意義,因為

WHERE timestamp > @startDT

WHERE timestamp < @endDT

導致時間戳在范圍內,但您的描述

 . .  * | * * * * * | * . . .
      start        end

上圖只是簡單的將*s的記錄顯示為我需要的記錄,而|...| 是界限。

意味着不同的東西。

所以遵循描述並使用以下映射

myTable = Posts
value = score
timestamp  = creationdate 

我在 data.stackexchange.com 上寫了這個查詢(根據 exodream 的答案修改,但比較運算符的方向 正確

DECLARE @START_DATE datetime
DECLARE @END_DATE datetime
SET @START_DATE = '2010-10-20'
SET @END_DATE = '2010-11-01'

SELECT score, 
       creationdate 
FROM   posts 
WHERE  creationdate BETWEEN (SELECT TOP 1 creationdate 
                             FROM   posts 
                             WHERE  creationdate < @START_DATE 
                             ORDER  BY creationdate DESC) 
                             AND 
                                   (SELECT TOP 1 creationdate 
                                    FROM   posts 
                                    WHERE  creationdate > @END_DATE 
                                    ORDER  BY creationdate ASC) 
ORDER by creationDate

哪個輸出

score creationdate        
----- ------------------- 
4     2010-10-19 23:55:48 
3     2010-10-20 2:24:50   
6     2010-10-20 2:55:54  
...
...
7     2010-10-31 23:14:48 
4     2010-10-31 23:18:17 
4     2010-10-31 23:18:48 
0     2010-11-01 3:59:38  

(382 row(s) affected)

請注意第一行和最后一行如何超出范圍的限制

您可以將這些有序查詢放入子查詢中,以避免無法直接 UNION 它們。 有點煩人,但它會給你你想要的。

SELECT value, timestamp 
 FROM myTable
 WHERE timestamp BETWEEN @startDT AND @endDT
 UNION
 SELECT value, timestamp 
 FROM (
 SELECT TOP 1
   value, timestamp
 FROM myTable
 WHERE timestamp > @startDT
 ORDER BY value, timestamp DESC 
 ) x
 UNION
 SELECT value, timestamp
 FROM (
 SELECT TOP 1
   value, timestamp
 FROM myTable
 WHERE timestamp < @endDT
 ORDER BY value, timestamp ASC
 ) x

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM