我有一个类似于以下示例的表结构:
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和key字段,我想要一个查询输出每个值的最小和最大日期时间,以便它显示如下所示:
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
如果有多行具有相同的最小/最大值,则应该获得最新的一行。
使用Inner Join在一个字段上,我知道要获取字段的最小/最大行的详细信息,但只有这样我才能认为在一个查询中获取所有内容是将它们全部合并。我认为可能有更好的解决方案。任何帮助表示赞赏。
我正在使用SQL Server 2008。
感谢。
答案 0 :(得分:2)
嘿presto ...
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];
答案 1 :(得分: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
答案 2 :(得分: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 |
+-----------+-----------+-----------+-----------+
答案 3 :(得分: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
搜索最大值。
答案 4 :(得分:0)
我读到了这个问题并且想到了:我宁愿在PHP中做这个而不是sql。
然后我读了答案,我想:我真的而不是在PHP中而不是sql。