我遇到一种情况,我需要获取列的 min() 和 max() 以及与 min() 和 max() 函数对应的另一列。我尝试过使用 INNER JOIN 进行查询,使用 min() 或 max() 时成功。当两者都使用时,不会返回任何内容。
SELECT A.IslandCode, CONVERT(DATE, A.LogTime)LogTime
, MN.Demand MinDemand, MN.TIME MinDemandAt
FROM
(
SELECT IslandCode, CONVERT(DATE, LogTime) LogTime, SUM(KiloWatt) Demand
FROM ph_MachineDailyReadings
WHERE IslandCode = 1 AND CONVERT(DATE, LogTime) = '2013-08-13'
GROUP BY IslandCode, LogTime
) A
INNER JOIN
(
SELECT TOP 1 IslandCode, CONVERT(DATE, LogTime) LogTime, SUM(KiloWatt) Demand,
STR(DATEPART(HOUR, LogTime)) + ':' + LTRIM(STR(DATEPART(MINUTE, LogTime))) TIME
FROM ph_MachineDailyReadings
WHERE IslandCode = 1 AND CONVERT(DATE, LogTime) = '2013-08-13'
GROUP BY IslandCode, LogTime
ORDER BY Demand
) MN
ON A.IslandCode = MN.IslandCode AND A.LogTime = MN.LogTime AND A.Demand = MN.Demand
上面的查询返回以下结果,这是正确的
IslandCode LogTime MinDemand MinDemandAt
1 2013-08-13 698 13:0
查询 max()
SELECT A.IslandCode, CONVERT(DATE, A.LogTime)LogTime
, MX.Demand MaxDemand, MX.TIME MaxDemandAt
FROM
(
SELECT IslandCode, CONVERT(DATE, LogTime) LogTime, SUM(KiloWatt) Demand
FROM ph_MachineDailyReadings
WHERE IslandCode = 1 AND CONVERT(DATE, LogTime) = '2013-08-13'
GROUP BY IslandCode, LogTime
) A
INNER JOIN
(
SELECT TOP 1 IslandCode, CONVERT(DATE, LogTime) LogTime, SUM(KiloWatt) Demand,
STR(DATEPART(HOUR, LogTime)) + ':' + LTRIM(STR(DATEPART(MINUTE, LogTime))) TIME
FROM ph_MachineDailyReadings
WHERE IslandCode = 1 AND CONVERT(DATE, LogTime) = '2013-08-13'
GROUP BY IslandCode, LogTime
ORDER BY Demand DESC
) MX
ON A.IslandCode = MX.IslandCode AND A.LogTime = MX.LogTime AND A.Demand = MX.Demand
返回,这也是正确的
IslandCode LogTime MaxDemand MaxDemandAt
1 2013-08-13 1463 20:0
但是当两个查询在同一个查询中使用时,不返回任何内容
SELECT A.IslandCode, CONVERT(DATE, A.LogTime)LogTime
, MX.Demand MaxDemand, MX.TIME MaxDemandAt
, MN.Demand MinDemand, MN.TIME MinDemandAt
FROM
(
SELECT IslandCode, CONVERT(DATE, LogTime) LogTime, SUM(KiloWatt) Demand
FROM ph_MachineDailyReadings
WHERE IslandCode = 1 AND CONVERT(DATE, LogTime) = '2013-08-13'
GROUP BY IslandCode, LogTime
) A
INNER JOIN
(
SELECT TOP 1 IslandCode, CONVERT(DATE, LogTime) LogTime, SUM(KiloWatt) Demand,
STR(DATEPART(HOUR, LogTime)) + ':' + LTRIM(STR(DATEPART(MINUTE, LogTime))) TIME
FROM ph_MachineDailyReadings
WHERE IslandCode = 1 AND CONVERT(DATE, LogTime) = '2013-08-13'
GROUP BY IslandCode, LogTime
ORDER BY Demand DESC
) MX
ON A.IslandCode = MX.IslandCode AND A.LogTime = MX.LogTime AND A.Demand = MX.Demand
INNER JOIN
(
SELECT TOP 1 IslandCode, CONVERT(DATE, LogTime) LogTime, SUM(KiloWatt) Demand,
STR(DATEPART(HOUR, LogTime)) + ':' + LTRIM(STR(DATEPART(MINUTE, LogTime))) TIME
FROM ph_MachineDailyReadings
WHERE IslandCode = 1 AND CONVERT(DATE, LogTime) = '2013-08-13'
GROUP BY IslandCode, LogTime
ORDER BY Demand
) MN
ON A.IslandCode = MN.IslandCode AND A.LogTime = MN.LogTime AND A.Demand = MN.Demand
预期结果
IslandCode LogTime MinDemand MinDemandAt MaxDemand MaxDemandAt
1 2013-08-13 1463 20:0 698 13:0
我可以在单个查询中获得此结果还是需要采用基于存储过程的解决方案?
提前致谢
最佳答案
您可以使用分析函数来做到这一点:
WITH Data AS
( SELECT IslandCode,
LogDate = CAST(LogTime AS DATE),
LogTime,
Demand = SUM(KiloWatt) ,
RowNumAsc = ROW_NUMBER() OVER (PARTITION BY IslandCode, CAST(LogTime AS DATE) ORDER BY SUM(Kilowatt)),
RowNumDesc = ROW_NUMBER() OVER (PARTITION BY IslandCode, CAST(LogTime AS DATE) ORDER BY SUM(Kilowatt) DESC)
FROM ph_MachineDailyReadings
WHERE IslandCode = 1
AND CAST(LogTime AS DATE) = '20130813'
GROUP BY IslandCode, LogTime
)
SELECT ma.IslandCode,
LogTime = ma.LogDate,
MinDemand = mi.Demand,
MinDemandAt = CAST(mi.LogTime AS TIME),
MaxDemand = ma.Demand,
MaxDemandAt = CAST(ma.LogTime AS TIME)
FROM Data mi
INNER JOIN Data ma
ON ma.IslandCode = mi.IslandCode
AND ma.LogDate = mi.LogDate
WHERE mi.RowNumAsc = 1
AND ma.RowNumDesc = 1;
编辑
这不需要参数,如果省略 WHERE
子句,如下所示,它将返回每个日期的每个岛屿代码的最小值和最大值:
WITH Data AS
( SELECT IslandCode,
LogDate = CAST(LogTime AS DATE),
LogTime,
Demand = SUM(KiloWatt) ,
RowNumAsc = ROW_NUMBER() OVER (PARTITION BY IslandCode, CAST(LogTime AS DATE) ORDER BY SUM(Kilowatt)),
RowNumDesc = ROW_NUMBER() OVER (PARTITION BY IslandCode, CAST(LogTime AS DATE) ORDER BY SUM(Kilowatt) DESC)
FROM ph_MachineDailyReadings
GROUP BY IslandCode, LogTime
)
SELECT ma.IslandCode,
LogTime = ma.LogDate,
MinDemand = mi.Demand,
MinDemandAt = CAST(mi.LogTime AS TIME),
MaxDemand = ma.Demand,
MaxDemandAt = CAST(ma.LogTime AS TIME)
FROM Data mi
INNER JOIN Data ma
ON ma.IslandCode = mi.IslandCode
AND ma.LogDate = mi.LogDate
WHERE mi.RowNumAsc = 1
AND ma.RowNumDesc = 1;
最后一点,我已将您的 logTime 采用 TIME 格式,因为这似乎比 VARCHAR 格式更有用,如果您确实需要 VARCHAR 格式,您可以使用:
CONVERT(VARCHAR(10), ma.LogTime, 8)
关于sql - 获取与 SQL Server 2008 中一列的 MIN 和 MAX 值对应的其他列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18273353/