2017-08-29 622 views
0

我對SQL很陌生,請耐心等待!我試圖寫一個T-SQL查詢(SSMS)從數據庫中檢索兩個不同的最大「數量」來自同一個「名稱」值,命名爲「meter_data」,在下面的格式:SQL Server查詢同一列中的多個值

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子句?

沒有要求免費的代碼,但如果有人可以指向我在正確的方向我會很感激!

謝謝。

+1

你必須使用'組by':'SELECT名稱,數量,MAX (價值)FROM meter_data GROUP BY名稱,數量' – Marcelo

+0

@Marcelo你有正確的答案,但你不需要這個名字嗎?選擇max(value)作爲最大值,從meter_data組中按數量選擇數量; – markg

+0

不,我不需要結果中的名稱,只是特定儀表的'Amps'和'Volts'的最大值。 – EnergyAuto

回答

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; 

您的查詢不工作,因爲電壓和電流是從不在同一行,因此AND總是假的。

如果你想要的話,你也許可以通過窗口化的東西來做一些優雅的OVER(..)分區,所以你可以看看。

HTH

+0

謝謝!我會研究OVER子句。 UNION ALL的棘手問題是數據庫中會有超過500,000行,並且2500米......並且正在增長! – EnergyAuto

+0

你不需要做任何UNION ALL,我只是在我的CTE中做了這些來模擬你粘貼到問題中的數據。你只需要看看查詢的底部部分 – markg

+0

啊!仍在學習!謝謝。 – EnergyAuto

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 
相關問題