2010-07-13 175 views
1

我有3個表:快速SQL問題

User (PK userid, ...) 
Computer (PK computerid, FK userid, FK cpuid, ...) 
CPU (PK cpuid, ...) 

因此,用戶可以擁有多臺電腦,並且每臺計算機都有一個確切的CPU。相同的cpu可以出現在不同的計算機上。

我想獲得每個用戶的計算機數量和獨特的CPU數量。

userid | Number of computers | Number of CPUs 
--------------------------------------------- 
    1 | 3     | 1  <- has 3 comps all with the same cpu 
    2 | 13     | 4  <- has 13 comps with 4 different cpus 
...and so on 

我沒有計算計算機的問題,但我堅持計算CPU。加入表會導致不好的結果,因爲如果在同一臺計算機上出現相同的CPU - count()返回總記錄數,就好像它們沒有分組一樣...

+0

爲什麼不把它當做兩個查詢呢? – 2010-07-13 10:17:29

回答

4

您不需要連接,因爲您可以計數該ID代替使用COUNT(*)。在這種情況下,您的查詢將是:

SELECT userid, COUNT(DISTINCT computerid) AS Computers, COUNT(DISTINCT cpuid) AS CPUs 
FROM Computer 
GROUP BY userid 
+0

這不包括當前沒有電腦的用戶。 – 2010-07-13 10:26:35

+0

這是錯誤的答案 - CPU數量不正確。 – PawelRoman 2010-07-13 10:26:44

+0

等待..不應該是'COUNT(DISTINCT computerid)'和'COUNT(DISTINCT cpuid)'? – 2010-07-13 10:27:49

1

這是最合乎邏輯的解決方案......

SELECT userid, 
     (SELECT COUNT(*) 
      FROM Computer 
      WHERE userid = User.userid 
     ) num_computers, 
     (SELECT COUNT(*) 
      FROM CPU 
     WHERE EXISTS (
       SELECT * 
        FROM Computer 
       WHERE cpuid = CPU.cpuid 
        AND userid = User.userid 
       ) 
     ) AS num_cpus 
    FROM User 

...但它是相當混亂的SQL(也可能很慢)。以下是一個更友好的SQL安排:

SELECT userid, 
     (SELECT COUNT(*) 
      FROM Computer 
      WHERE userid = User.userid 
     ) num_computers, 
     (SELECT COUNT(DISTINCT cpuid) 
      FROM CPU 
      JOIN Computer USING(cpuid) 
     WHERE userid = User.userid 
     ) AS num_cpus 
    FROM User 
-1

您的表未規範化。您應該在CPU和計算機之間創建一個關聯實體。把它叫做CompCpu,就像電腦和CPU一樣。

如果你這樣做,你可以輕鬆地內部加入的東西。它應該大致如下....

SELECT u.userid, COUNT(c.computerid), COUNT(cpu.cpuid) 
FROM User u 
INNER JOIN Computer c ON u.userid = c.userid 
INNER JOIN CompCpu cc ON c.computerid = cc.computerid 
INNER JOIN CPU cpu ON cpu.cpuid = cc.cpuid 
GROUP BY u.userid 
+0

這將允許每臺計算機有多個CPU,這在問題陳述中被明確禁止。 – 2010-07-13 10:28:23

1

應涵蓋所有的情況。(即使用戶沒有電腦..)

SELECT 
    User.UserId, 
    COUNT(Computer.ComputerId) AS [Computer #], 
    COUNT(DISTINCT Computer.CpuId) AS [CPU #] 
FROM 
    User 
    LEFT OUTER JOIN 
    Computer ON Computer.UserId = User.UserId 
GROUP BY 
    User.UserId 
1

這將包括用戶帶或不帶電腦,並處理不同的CPU數數。

我複製你的SQL表這樣

架構

用戶

ID - Int (PK) 
Name - Nvarchar(50) 

表的CPU

CPUID - Int (PK) 
Name - Nvarchar(50) 

表計算機

CompID - Int(PK) 
CPUID - Int(FK) 
UserID - Int(FK) 
Name - Nvarchar(50) 

表數據

用戶

ID Name 
1 Tommy 
2 Steve 
3 Jeff 

計算機

ID  UserID  CPUID  Name 
1  1   1   Dell 1 
2  1   1   Dell 2 
3  1   1   Dell 3 
4  2   3   Dell 4 
5  2   3   Dell 5 
6  2   4   Dell 6 

的CPU

CPUID  Name 
1   Intel 1 
2   Intel 2 
3   AMD 1 
4   AMD 2 

查詢

SELECT  COUNT(DISTINCT Computers.CPUID) AS CPUs, COUNT(Computers.ComputerID) 
AS numComputers, Users.Name 
FROM   Computers RIGHT OUTER JOIN 
         Users ON Computers.UserID = Users.UserID 
GROUP BY Users.Name 

結果

CPUs  numComputers  Name 
0   0    Jeff 
2   3    Steve 
1   3    Tommy 
0

嘗試

select 
    [user].userid, 
    COUNT(computerid) AS Computers, 
    COUNT(distinct CpuID) AS CpuModels 
from [user] left outer join computer on [user].userid=computer.userid 
group by [user].userid 

LEFT OUTER JOIN將返回所有用戶,但僅匹配計算機。如果用戶沒有計算機,它將返回來自計算機(ComputerID,CpuID)的字段的NULL值。 COUNT()不計數NULL,因此您從沒有計算機的用戶那裏獲得0臺計算機。您需要DISTINCT CpuID才能計算CpuID的不同值而不是所有實例。