我是SQL新手所以请耐心等待!我正在尝试编写一个T-SQL查询(SSMS)来检索两个不同的最大值"数量"来自同一个"名称"的值从数据库中,以下面的格式调用它" meter_data":
Name Date Time Value Quantity
------------------------------------------
Meter1 29-08-17 19:00 2.1 Amps
Meter1 29-08-17 19:30 2.5 Amps
Meter1 29-08-17 20:00 2.2 Amps
Meter1 29-08-17 19:00 231 Volts
Meter1 29-08-17 19:30 232 Volts
Meter1 29-08-17 20:00 235 Volts
Meter2 29-08-17 19:00 16.1 Amps
Meter2 29-08-17 19:30 17 Amps
Meter2 29-08-17 20:00 17.1 Amps
Meter2 29-08-17 19:00 415 Volts
Meter2 29-08-17 19:30 413 Volts
Meter2 29-08-17 20:00 412 Volts
etc... etc... etc... etc...
查询结果应返回以下数据:
Meter 1
Amps 2.5
Volts 235
这是我的问题:
SELECT MAX(Value)
FROM meter_data
WHERE Name = 'Meter1'
AND (Quantity = 'Amps')
AND (Quantity = 'Volts')
以上结果是:
Meter1
NULL
查询显然不正确,因为它将两个Quantity
组合在一起并返回NULL值。我已经尝试了几种不同的方法来实现这一目标(INNER JOIN
,IN
,INTERSECT
...)但是对于我的生活,我无法弄清楚我哪里出错了。是否应该有另一个WHERE子句?
不要求免费的代码,但如果有人能指出我正确的方向,我将非常感激!
感谢。
答案 0 :(得分:1)
你可以通过几种不同的方式做到这一点,这里有一个机会。 一种方法就是这样,只需使用一个联合来组合你的结果。 (CTE只是为了模仿你的桌子)
with x as
(
select 'Meter1' AS METER, 2.1 AS AMOUNT ,'Amps' AS PTYPE
union ALL
select'Meter1', 2.5 , 'Volts'
union ALL
select'Meter1', 2.2 , 'Volts'
union ALL
select'Meter1', 231 , 'Volts'
union ALL
select'Meter1', 232 , 'Volts'
union ALL
select'Meter1', 235 , 'Volts'
union ALL
select'Meter2', 16.1 ,'Amps'
union ALL
select'Meter2', 17 ,'Amps'
union ALL
select'Meter2', 17.1 ,'Amps'
union ALL
select'Meter2' , 415 , 'Volts'
union ALL
select'Meter2', 413 , 'Volts'
union ALL
select'Meter2' , 412, 'Volts'
)
SELECT MAX(X.AMOUNT) AS AMOUNT, 'AMPS' FROM X WHERE X.PTYPE='AMPS'
UNION
SELECT MAX(X.AMOUNT) AS AMOUNT, 'VOLTS' FROM X WHERE X.PTYPE='VOLTS'
或者你可以更像一个枢轴,这看起来像这样
with x as
(
select 'Meter1' AS METER, 2.1 AS AMOUNT ,'Amps' AS PTYPE
union ALL
select'Meter1', 2.5 , 'Volts'
union ALL
select'Meter1', 2.2 , 'Volts'
union ALL
select'Meter1', 231 , 'Volts'
union ALL
select'Meter1', 232 , 'Volts'
union ALL
select'Meter1', 235 , 'Volts'
union ALL
select'Meter2', 16.1 ,'Amps'
union ALL
select'Meter2', 17 ,'Amps'
union ALL
select'Meter2', 17.1 ,'Amps'
union ALL
select'Meter2' , 415 , 'Volts'
union ALL
select'Meter2', 413 , 'Volts'
union ALL
select'Meter2' , 412, 'Volts'
)
select Max(case when X.PTYPE='AMPS' then amount end) as 'amps',
Max(case when X.PTYPE='volts' then amount end) as 'volts'
from x;
您的查询无法正常工作,因为VOLTS和AMPS永远不会在同一行,因此AND始终为false。
如果你愿意的话,你可以通过窗口化东西来做一些优雅的OVER(..)分区,所以你可以考虑一下。
HTH
答案 1 :(得分:1)
以下是两种不同的选择......
SET NOCOUNT ON;
IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL
DROP TABLE #TestData;
CREATE TABLE #TestData (
[Name] CHAR(6) NOT NULL,
[Date Time] DATETIME2(0) NOT NULL,
[Value] DECIMAL(9,1) NOT NULL ,
Quantity VARCHAR(5) NOT NULL
);
SET DATEFORMAT 'DMY';
INSERT #TestData (Name, [Date Time], Value, Quantity) VALUES
('Meter1', '29-08-2017 19:00', 2.1, 'Amps'),
('Meter1', '29-08-2017 19:30', 2.5, 'Amps'),
('Meter1', '29-08-2017 20:00', 2.2, 'Amps'),
('Meter1', '29-08-2017 19:00', 231, 'Volts'),
('Meter1', '29-08-2017 19:30', 232, 'Volts'),
('Meter1', '29-08-2017 20:00', 235, 'Volts'),
('Meter2', '29-08-2017 19:00', 16.1, 'Amps'),
('Meter2', '29-08-2017 19:30', 17, 'Amps'),
('Meter2', '29-08-2017 20:00', 17.1, 'Amps'),
('Meter2', '29-08-2017 19:00', 415, 'Volts'),
('Meter2', '29-08-2017 19:30', 413, 'Volts'),
('Meter2', '29-08-2017 20:00', 412, 'Volts');
--===========================================================
-- 2 rows per meter...
WITH
cte_AddRank AS (
SELECT
td.Name, td.[Date Time], td.Value, td.Quantity,
DR = DENSE_RANK() OVER (PARTITION BY td.Name, td.Quantity ORDER BY td.Value DESC)
FROM
#TestData td
)
SELECT
ar.Name, ar.Quantity, ar.Value
FROM
cte_AddRank ar
WHERE
ar.DR = 1;
--================================================
-- 1 row per meter (pivioted)...
SELECT
td.Name,
Amps = MAX(CASE WHEN td.Quantity = 'Amps' THEN td.Value END),
Volts = MAX(CASE WHEN td.Quantity = 'Volts' THEN td.Value END)
FROM
#TestData td
GROUP BY
td.Name;
结果...
-- 2 rows per meter...
Name Quantity Value
------ -------- ---------------------------------------
Meter1 Amps 2.5
Meter1 Volts 235.0
Meter2 Amps 17.1
Meter2 Volts 415.0
-- 1 row per meter (pivioted)...
Name Amps Volts
------ --------------------------------------- ---------------------------------------
Meter1 2.5 235.0
Meter2 17.1 415.0