2009-08-07 184 views
0

我有这些表:复杂的SQL查询

 
- Users 
    - id 
- Photos 
    - id 
    - user_id 
- Classifications 
    - id 
    - user_id 
    - photo_id 

我想通过照片,他们自己的分类+的总数订购用户。

我写此查询:

 
SELECT users.id, 
COUNT(photos.id) AS n_photo, 
COUNT(classifications.id) AS n_classifications, 
(COUNT(photos.id) + COUNT(classifications.id)) AS n_sum 
FROM users 
LEFT JOIN photos ON (photos.user_id = users.id) 
LEFT JOIN classifications ON (classifications.user_id = users.id) 
GROUP BY users.id 
ORDER BY (COUNT(photos.id) + COUNT(classifications.id)) DESC 

的问题是,我希望这个查询不起作用,并且返回高的数字,而我只有一个数据库中的几张照片和分类。它返回如下所示的内容:

id n_photo n_classifications n_sum 
29 19241 19241     38482 
16 16905 16905     33810 
1 431  0      431 
...
+0

我们都假设SQL服务器 - 是否正确?什么版本? – 2009-08-07 08:49:04

+0

对不起,这是MySQL ... – collimarco 2009-08-07 09:09:09

回答

3

你错过了不同。

SELECT U.ID, COUNT(DISTINCT P.Id)+COUNT(DISTINCT C.Id) Count 
    FROM User U 
    LEFT JOIN Photos P ON P.User_Id=U.Id 
    LEFT JOIN Classifications C ON C.User_Id=U.Id 
    GROUP BY U.Id 
    ORDER BY COUNT(DISTINCT P.Id)+COUNT(DISTINCT C.ID) 
+0

谢谢!现在一切正常。我仍然有疑问:为什么我需要使用DISTINCT?它有什么作用? – collimarco 2009-08-07 09:15:57

+0

因为您没有加入照片和分类,所以您基本上将它们交叉连接起来,为每个分类选择每张照片。如果用户只能分类自己的照片,则可以将“AND C.PhotoId = P.Id”添加到分类连接中。 – 2009-08-07 10:27:01

1

我可能误解你的模式,但不应该这样:

LEFT JOIN classifications ON (classifications.user_id = users.id) 

是这样的:

LEFT JOIN classifications ON (classifications.user_id = users.id) 
         AND (classifications.photo_id = photos.id) 

+0

这会假定所有分类都是针对相同的用户照片。 – 2009-08-07 08:43:49

0
SELECT users1.id, users1.n_photo, users2.n_classifications 
FROM (
    SELECT users.id, COUNT(photos.id) AS n_photo 
    FROM users LEFT OUTER JOIN photos ON photos.user_id = users.id 
    GROUP BY users.id 
) users1 
    INNER JOIN (
    SELECT users.id, COUNT(classifications.id) AS n_classifications 
    FROM users LEFT OUTER JOIN classifications ON classifications.user_id = users.id 
    GROUP BY users.id 
) users2 ON users1.id = users1.id 
0

尝试一些更喜欢这个:

SELECT users.id as n_id, 
(SELECT COUNT(photos.id) FROM photos WHERE photos.user_id = n_id) AS n_photos, 
(SELECT COUNT(classifications,id) FROM classifications WHERE classifications.user_id = n_id) AS n_classifications, 
(n_photos + n_classifications) AS n_sum 
FROM users 
GROUP BY n_id 
ORDER BY n_sum DESC