2010-07-13 172 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的不同值而不是所有实例。