2010-08-11 59 views
3

嗨的範圍內,我想根據範圍來創建一個SQL到組記錄如何分組記錄根據SQL

例如,假設我有

Number Time   Price 
100 20100810   10.0 
100 20100812   15.0 
160 20100810   10.0 
200 20100810   12.0 
210 20100811   13.0 
300 20100811   14.0 
350 20100810   16.0 

現在我需要根據「編號」的範圍獲取記錄:[100,200),[200,300),[300,400) and [0,400]。對於每一個範圍,我需要的最新的「時代」

的「價格」所以結果應該是

NumberRange   Time   Price 
    1   20100812   15.0 
    2   20100811   13.0 
    3   20100811   14.0 
    4   20100812   15.0 

我怎樣才能構建一個SQL語句來生產呢?

我沒有在特定的數據庫上工作。所以我正在尋找沒有特定數據庫的SQL語句

+0

這可能因平臺而異。你使用什麼樣的SQL? – kbrimington 2010-08-11 21:31:44

回答

4

用途:

SELECT x.rank, x.time, x.price 
    FROM (SELECT *, 
       CASE 
        WHEN number BETWEEN 100 and 199 THEN 1 
        WHEN number BETWEEN 200 and 299 THEN 2 
        WHEN number BETWEEN 300 and 399 THEN 3 
        ELSE NULL 
       END AS rank 
      FROM TABLE) x 
      JOIN (SELECT t.rank, 
         MAX(t.time) AS max_time 
        FROM (SELECT *, 
           CASE 
            WHEN number BETWEEN 100 and 199 THEN 1 
            WHEN number BETWEEN 200 and 299 THEN 2 
            WHEN number BETWEEN 300 and 399 THEN 3 
            ELSE NULL 
           END AS rank 
          FROM TABLE) t 
       GROUP BY t.rank) y ON y.rank = x.rank 
           AND y.max_time = x.time 
UNION ALL 
SELECT x.rank, x.time, x.price 
    FROM (SELECT *, 
       CASE 
       WHEN number BETWEEN 0 and 400 THEN 4 
       ELSE NULL 
       END AS rank 
      FROM TABLE) x 
      JOIN (SELECT t.rank, 
         MAX(t.time) AS max_time 
        FROM (SELECT *, 
           CASE 
           WHEN number BETWEEN 0 and 400 THEN 4 
           ELSE NULL 
           END AS rank 
          FROM TABLE) t 
       GROUP BY t.rank) y ON y.rank = x.rank 
           AND y.max_time = x.time 
+0

我的定義錯過了原始問題中的一些東西。發送這個長的答案。 – Tobiasopdenbrouw 2010-08-11 21:46:44

0

家庭作業?

您可以通過if語句選擇附加列來確定相關的範圍ID。然後按這個新列進行分組。

0

雖然以下一些需要核心標準SQL外部的秋天,他們是完全標準的SQL功能(例如,行構造函數是一個完整的SQL-92功能,熱膨脹係數是一個完整的SQL- 99功能等),並確實可以在某些產品(如SQL Server和Oracle)中找到:

WITH MyTable (my_Number, my_Time, Price) 
    AS 
    (
     SELECT my_Number, CAST(my_Time AS DATE), 
      CAST(Price AS DECIMAL(5, 2)) 
     FROM (
       VALUES (100, '2010-08-10', 10), 
        (100, '2010-08-12', 15), 
        (160, '2010-08-10', 10), 
        (200, '2010-08-10', 12), 
        (210, '2010-08-11', 13), 
        (300, '2010-08-11', 14), 
        (350, '2010-08-10', 16) 
      ) AS MyTable (my_Number, my_Time, Price) 
    ), Ranges (NumberRange, range_start, range_end) 
    AS 
    (
     SELECT NumberRange, range_start, range_end 
     FROM (
       VALUES (1, 100, 200), 
        (2, 200, 300), 
        (3, 300, 400), 
        (4, 0, 400) 
      ) AS Ranges (NumberRange, range_start, range_end) 
    ), 
    RangesMaxTimes (NumberRange, range_start, range_end, max_time) 
    AS 
    ( 
     SELECT R1.NumberRange, 
      R1.range_start, R1.range_end, 
      MAX(M1.my_Time) AS max_time 
     FROM MyTable AS M1 
     INNER JOIN Ranges AS R1 
      ON R1.range_start <= M1.my_Number 
      AND M1.my_Number < R1.range_end 
     GROUP 
      BY R1.NumberRange, R1.range_start, R1.range_end 
    ) 
SELECT R1.NumberRange, M1.my_Time, M1.Price 
    FROM MyTable AS M1 
     INNER JOIN RangesMaxTimes AS R1 
      ON R1.range_start <= M1.my_Number 
      AND M1.my_Number < R1.range_end 
      AND M1.my_Time = R1.max_time;