2009-12-13 90 views
0

我有類似下面的示例表結構:查詢來獲取最大/最小行細節多個字段

DateTime    V1 V2 V3 V4  
10/10/10 12:10:00  71 24 33 40 
10/10/10 12:00:00  75 22 44 12 
10/10/10 12:30:00  44 21 44 33 
10/10/10 12:20:00  80 11 88 12 

隨着DateTime字段作爲unqiue和關鍵領域,我想查詢輸出分鐘,最大日期時間爲每個值,這樣它會顯示類似如下:

TYPE MIN  MINDATETIME   MAX  MAXDATETIME 
V1  44  10/10/10 12:30:00 80  10/10/10 12:20:00 
V2  11  10/10/10 12:20:00 24  10/10/10 12:10:00 
V3  33  10/10/10 12:10:00 88  10/10/10 12:20:00 
V4  12  10/10/10 12:20:00 40  10/10/10 12:10:00 

如果有與同一最小值/最大值多行,那麼就應該獲得最新的一個。

隨着內部加入一個字段,我知道要獲取最小/最大行的細節,但只有這樣我才能認爲在一個查詢中獲取所有內容都將它們聯合起來。我認爲可能會有更好的解決方案。任何幫助表示讚賞。

我正在使用SQL Server 2008.

謝謝。

+0

我想工會4查詢是否是我,也許有更好的方法。 – 2009-12-13 15:22:57

+0

什麼RDBMS和版本?你是否需要與輸出一樣的數據?如果你這樣做的話,這是一個UNPIVOT,然後是聚合物。 – gbn 2009-12-13 15:44:20

+0

我正在使用sql server 2008.是的主要想法是獲取對應於類型的最小值和最大值的日期時間。 – sajoz 2009-12-13 15:47:12

回答

2
  • 逆透視成有用行(「規範」)
  • 每類工作了MIN/MAX,允許MAX日期時間,如果關係
  • 提取最小值/最大值

變戲法似的......

DECLARE @foo TABLE (
    DateTimeKey datetime NOT NULL, 
    V1 int NOT NULL, 
    V2 int NOT NULL, 
    V3 int NOT NULL, 
    V4 int NOT NULL 
); 

INSERT @foo (DateTimeKey, V1, V2, V3, V4) 
SELECT '10/10/10 12:10:00',  71, 24, 33, 40 
UNION ALL SELECT '10/10/10 12:00:00',  75, 22, 44, 12 
UNION ALL SELECT '10/10/10 12:30:00',  44, 21, 44, 33 
UNION ALL SELECT '10/10/10 12:20:00',  80, 11, 88, 12; 


WITH cTE AS 
(
    SELECT 
     [Type], [Value], DateTimeKey, 
     ROW_NUMBER() OVER (PARTITION BY [Type] ORDER BY [Value], DateTimeKey DESC) AS TypeRankMin, 
     ROW_NUMBER() OVER (PARTITION BY [Type] ORDER BY [Value] DESC, DateTimeKey DESC) AS TypeRankMax 
    FROM 
     (
     SELECT 
      [Type], [Value], DateTimeKey 
     FROM 
      (SELECT DateTimeKey, V1, V2, V3, V4 FROM @foo) p 
      UNPIVOT 
      ([Value] FOR [Type] IN (V1, V2, V3, V4)) AS unp 
     ) bar 
) 
SELECT 
    Mn.[Type], [MIN], MINDATETIME, [MAX], MAXDATETIME 
FROM 
    (
     SELECT 
      [Type], [Value] AS [MIN], DateTimeKey AS MINDATETIME 
     FROM 
      cTE 
     WHERE 
      TypeRankMin = 1 
    ) Mn 
    JOIN 
    (
     SELECT 
      [Type], [Value] AS [MAX], DateTimeKey AS MAXDATETIME 
     FROM 
      cTE 
     WHERE 
      TypeRankMax = 1 
    ) Mx ON Mn.[Type] = Mx.[Type]; 
+0

這是偉大的gbn。它工作完美。但一個問題:我修改查詢只有MAX值,只是爲了比較這與我的查詢的性能,因爲我只有最大值(我的查詢如前面提到的每個值字段的內部聯接的聯合)。爲大約一張桌子。在18個值字段(v1,v2等)上有82000行,我在4秒左右得到了結果。但是這個查詢需要大約15秒。知道爲什麼? – sajoz 2009-12-13 18:35:23

+0

數據查詢的質量很差,這個解決方案做了很多處理。嘗試使用Andomar的解決方案進行比較 – gbn 2009-12-13 18:49:30

0

您可以在單個查詢中同時獲取最大值和最小值。爲了獲得最大/最小的日期時間,你將不得不加入最大/最小查詢回(每一次值)

一些表格的效果:

select values.*, mint.timestamp, maxt.timestamp from 
    (select MIN(value) as minv, MAX(value) as maxv from table group by value) values, 
    table mint, 
    table maxt 
where 
    mint.value = values.minv 
    maxt.value = values.maxv 
0

不知道這是否就是你都是經過,但似乎解決了這個基本情況:

create table t(a int,b int); 
insert into t(a,b) values(1,2),(2,3),(-1,-10); 

select max(t1.a),min(t1.a),max(t2.b),min(t2.b) from t as t1,t as t2; 
+-----------+-----------+-----------+-----------+ 
| max(t1.a) | min(t1.a) | max(t2.b) | min(t2.b) | 
+-----------+-----------+-----------+-----------+ 
|   2 |  -1 |   3 |  -10 | 
+-----------+-----------+-----------+-----------+ 
0

我會跟你的正常化數據起始位置。由於V2不依賴於V1,它們不應該在同一行。這是一個正常化查詢:

SELECT DateTime, 'V1' as Type, V1 as Value FROM @data 
UNION ALL select DateTime, 'V2', V2 FROM @data 
UNION ALL select DateTime, 'V3', V3 FROM @data 
UNION ALL select DateTime, 'V4', V4 FROM @data 

因此,剩下的是「選擇記錄保持組綁定最大值與綁定」問題。解決方法之一就是:

;WITH normal AS (
    SELECT DateTime, 'V1' as Type, V1 as Value FROM @data 
    UNION ALL select DateTime, 'V2', V2 FROM @data 
    UNION ALL select DateTime, 'V3', V3 FROM @data 
    UNION ALL select DateTime, 'V4', V4 FROM @data 
) 
SELECT * 
FROM (SELECT DISTINCT Type FROM normal) dd 
CROSS APPLY (
     SELECT TOP 1 DateTime MINDATETIME, Value MIN 
     FROM  normal di 
     WHERE di.Type = dd.Type 
     ORDER BY Value, DateTime desc 
     ) dimin 
CROSS APPLY (
     SELECT TOP 1 DateTime MAXDATETIME, Value MAX 
     FROM  normal di 
     WHERE di.Type = dd.Type 
     ORDER BY Value desc, DateTime desc 
     ) dimax 

dd查詢返回的類型(V1,V2,...)第一cross apply搜索的最小值爲該類型,而第二cross apply搜索的最大值。

0

我讀了這個問題,並認爲:我寧願這樣做在PHP比SQL。

然後我閱讀答案,我想:我會真的而不是在PHP比SQL。