快速SQL问题

时间:2010-07-13 10:14:45

标签: sql

我有3张桌子:

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()会返回总记录数,就好像它们没有被分组一样......

6 个答案:

答案 0 :(得分:4)

您不需要加入,因为您可以计算ID而不是使用COUNT(*)。在这种情况下,您的查询将是:

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

答案 1 :(得分: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

答案 2 :(得分: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

答案 3 :(得分: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

答案 4 :(得分: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的不同值而不是所有实例。

答案 5 :(得分:-1)

您的表格未正常化。您应该在CPU和计算机之间建立一个关联实体。称之为CompCpu,其中包含计算机和CPU的pk。

如果你这样做,你可以很容易地加入内容。它看起来应该大致......

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