![](/img/trans.png)
[英]Can I get the sum of the day, the week and the month in 1 MS SQL query?
[英]How can I get distinct average and sum values in one MS SQL query?
我正在嘗試在MS SQL Server 2012中創建一個查詢,該查詢為我提供了數據庫表中不同記錄的count
, average
和一些sum
值。 我將盡力解釋我的處境和願望。 如果仍然不清楚或需要一些其他信息,請告訴我。
下表TEMP
具有10條記錄:
表
╔════════╦═════════════╦════════╦═══════════╗
║ Number ║ DateOfBirth ║ Gender ║ Activity ║
╠════════╬═════════════╬════════╬═══════════╣
║ 191806 ║ 1940-08-31 ║ F ║ AMADMIN ║
║ 196484 ║ 1940-09-23 ║ F ║ AMHOST ║
║ 199480 ║ 1949-10-16 ║ F ║ AMTRAINER ║
║ 201089 ║ 1947-04-08 ║ M ║ AMTRAINER ║
║ 204528 ║ 1950-05-02 ║ F ║ AMHOST ║
║ 226356 ║ 1966-04-12 ║ M ║ AMADMIN ║
║ 226356 ║ 1966-04-12 ║ M ║ AMHOST ║
║ 377599 ║ 1985-05-15 ║ F ║ AMADMIN ║
║ 377599 ║ 1985-05-15 ║ F ║ AMHOST ║
║ 395809 ║ 1980-03-03 ║ F ║ AMADMIN ║
╚════════╩═════════════╩════════╩═══════════╝
現在,考慮運行以下查詢:
SQL
SELECT COUNT([Number]) AS Number, ROUND(AVG(CAST(DATEDIFF(DAY, [DateOfBirth], GETDATE()) / 365.2425 AS FLOAT)), 1) AS AverageAge,
SUM(CASE WHEN [Gender] = 'M' THEN 1 ELSE 0 END) AS Male,
SUM(CASE WHEN [Gender] = 'F' THEN 1 ELSE 0 END) AS Female
FROM [TEMP]
WHERE [Activity] IN ('AMHOST', 'AMADMIN', 'AMTRAINER')
此查詢將給我以下結果:
結果
╔════════╦════════════╦══════╦════════╗
║ Number ║ AverageAge ║ Male ║ Female ║
╠════════╬════════════╬══════╬════════╣
║ 10 ║ 57,3 ║ 3 ║ 7 ║
╚════════╩════════════╩══════╩════════╝
到現在為止還挺好! 但是現在是棘手的部分。 我真正想要的是表中所有distinct
記錄的結果。 這意味着計算所有的人減去兩個“雙”的人(其平均年齡和男/女數Number
226356
和377599
)。 因此,我需要一個產生以下結果的查詢:
想要的結果
╔════════╦════════════╦══════╦════════╗
║ Number ║ AverageAge ║ Male ║ Female ║
╠════════╬════════════╬══════╬════════╣
║ 8 ║ 56,9 ║ 2 ║ 6 ║
╚════════╩════════════╩══════╩════════╝
我知道如何為一條查詢獲取distinct
記錄,如下所示:
SQL
SELECT COUNT(DISTINCT([Number])) AS Number, ROUND(AVG(CAST(DATEDIFF(DAY, [DateOfBirth], GETDATE()) / 365.2425 AS FLOAT)), 1) AS AverageAge,
SUM(CASE WHEN [Gender] = 'M' THEN 1 ELSE 0 END) AS Male,
SUM(CASE WHEN [Gender] = 'F' THEN 1 ELSE 0 END) AS Female
FROM [TEMP]
WHERE [Activity] IN ('AMHOST', 'AMADMIN', 'AMTRAINER')
但這會產生:
結果
╔════════╦════════════╦══════╦════════╗
║ Number ║ AverageAge ║ Male ║ Female ║
╠════════╬════════════╬══════╬════════╣
║ 8 ║ 57,3 ║ 3 ║ 7 ║
╚════════╩════════════╩══════╩════════╝
現在Number
計數很好,但是AverageAge
, Male
和Female
值不正確。
我的問題是,如果甚至可以從這樣的查詢開始,該如何調整我的查詢以檢索WANTED RESULT集中顯示的值?
由於活動未出現在任何匯總函數中,因此您可以簡單地從結果中減去此值,並在匯總之前使用子查詢獲取不同的記錄,然后將COUNT(DISTINCT CASE..
應用於您的男性/女性人數:
SELECT COUNT(DISTINCT [Number]) AS Number,
ROUND(AVG(CAST(DATEDIFF(DAY, [DateOfBirth], GETDATE()) / 365.2425 AS FLOAT)), 1) AS AverageAge,
COUNT(DISTINCT CASE WHEN [Gender] = 'M' THEN [Number] END) AS Male,
COUNT(DISTINCT CASE WHEN [Gender] = 'F' THEN [Number] END) AS Female
FROM ( SELECT DISTINCT Number, DateOfBirth, Gender
FROM [sw_test].[dbo].[TEMP]
WHERE [Activity] IN ('AMHOST', 'AMADMIN', 'AMTRAINER')
) AS t;
您的查詢不能解決問題,因為您只告訴sql對列之一(數字)使用不同的數據點。 當sql移出括號並轉到下一列的計算時,它不再使用distinct命令。
為了解決您的問題,我建議使用子查詢。 還有其他方法可以做到這一點,但是我相信子查詢是您最好的選擇,因為您可以首先過濾數據,然后僅基於唯一的數據點進行數學運算。 並非數據點中的所有列都是具有重復數字的行中的重復項。 但是,這僅在活動列中(由於計算中不必要,我們可以忽略該列)。 我將假定性別和出生日期將始終相同。 現在,您的查詢將如下所示:
SELECT COUNT(DISTINCT(t.Number)) AS Number, ROUND(AVG(CAST(DATEDIFF(DAY, t.DateOfBirth, GETDATE()) / 365.2425 AS FLOAT)), 1) AS AverageAge,
SUM(CASE WHEN t.Gender = 'M' THEN 1 ELSE 0 END) AS Male,
SUM(CASE WHEN t.Gender = 'F' THEN 1 ELSE 0 END) AS Female
From
( Select t.number, t.DateOfBirth, t.Gender
From temp t
Where activity in ('AMHOST', 'AMADMIN', 'AMTRAINER')
Group by t.number, t.DateOfBirth, t.Gender) t
該查詢有效。 進行了一次子選擇以獲得基本設置。
SELECT COUNT([Number]) AS Number, ROUND(AVG(CAST(DATEDIFF(DAY, [DateOfBirth], GETDATE()) / 365.2425 AS FLOAT)), 1) AS AverageAge,
SUM(CASE WHEN [Gender] = 'M' THEN 1 ELSE 0 END) AS Male,
SUM(CASE WHEN [Gender] = 'F' THEN 1 ELSE 0 END) AS Female
FROM
(SELECT DISTINCT Number, DateOfBirth, Gender
FROM temp where [Activity] IN ('AMHOST', 'AMADMIN', 'AMTRAINER')) a
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.