2012-05-23 136 views
0

我有以下表格:包含在SQL查询一个一对多的关系计数

users 
+----------+----------+----------+ 
| id  | name  | dob  | 
+----------+----------+----------+ 

authentications 
+----------+----------+----------+ 
| id  | user_id | provider | 
+----------+----------+----------+ 

的用户,有一对多认证。 user_idauthentications表中是users表的外键。

我试着去COMPLE以下的输出:

+---------------+---------------+---------------+---------------+ 
| user.id | user.name | user.dob |  C  | 
+---------------+---------------+---------------+---------------+ 

这里,C是,用户认证,其中提供商的Facebook“的计数。如果不是count,我可以得到一个布尔值,也就是说,如果存在验证,则返回true,否则返回false,这会更好。

我不知道如何去构建查询。任何指针将不胜感激。

+0

您使用什么类型的SQL的? – msmucker0527

+0

如果你指的是什么数据库,我使用MySQL – zsquare

回答

0

1)这将返回的实际计数授权的类型FB的为每个用户:

`

Select Name UserName, ID UserID, COUNT(FBAuth) FBAuthCount 
from Users LEFT JOIN 
(Select UserID, COUNT(AuthType) FBAuth from Auth 
Where AuthType = 'FB' 
Group by USERID) Auths on (Users.ID = Auths.UserId) 
Group by ID, Name 

`

2)这将返回该标志真或对于每个用户而言都取决于其授权类型:

`

Select Name UserName, ID UserID, 
CASE WHEN COUNT(FBAuth) > 0 THEN 'TRUE' ELSE 'FALSE' END FBAuthFLAG 
from Users LEFT JOIN 
(Select UserID, COUNT(AuthType) FBAuth from Auth 
Where AuthType = 'FB' 
Group by USERID) Auths on (Users.ID = Auths.UserId) 
Group by ID, Name 

`

使用连接在较小的数据集:更快的响应。 最后,我相信这是一个:

`

SELECT users.id, 
     users.email, 
     users.name, 
     users.sid, 
     users.created_at, 
     (CASE 
      WHEN fb_auth > 0 
      THEN 'true' 
      ELSE 'false' 
     END) AS facebook 
FROM users 
     LEFT JOIN (SELECT authentications.user_id, 
         Count(authentications.provider) fb_auth 
        FROM authentications 
        WHERE provider = 'facebook' 
        GROUP BY user_id) auths 
       ON (users.id = auths.user_id) 
GROUP BY users.id, 
      users.email, 
      users.name, 
      users.sid, 
      users.created_at 

`

0

C是计数,如果有Facebook提供者,B将返回1,否则返回0(布尔值)。已更新为使用LEFT OUTER JOIN,以便包含所有用户。

SELECT 
    users.id, 
    users.name, 
    users.DOB, 
    SUM(CASE WHEN authentications.provider = 'facebook' then 1 else 0 end) as C, 
    MAX(CASE WHEN authentications.provider = 'facebook' then 1 else 0 end) as B 
FROM users 
LEFT OUTER JOIN authentications 
    ON users.id = authentications.user_id 
GROUP BY users.id, users.name, users.DOB 
+0

这个查询是否非常非常非常缓慢?我的系统挂起,即使我运行此限制为5 – zsquare

+0

取决于许多变量,如您的系统,表中的行数,索引等... – msmucker0527

2

使用用户与认证之间的JOIN创建查询,并首先在用户标识字段中添加GROUP BY。你组通过将需要包含您希望在搜索结果中列出后续字段虽然他们不会改变作用的结果:

SELECT u.id, u.name, u.dob, COUNT(a.user_id) as authCount 
FROM users u 
LEFT JOIN authentications a on u.id = a.user_id 
WHERE a.provider = 'facebook' 
GROUP BY u.id, u.name, u.dob 
+0

这只会返回用户的结果计数是> 0.我需要所有用户的结果。 – zsquare

+0

对不起。将INNER JOIN更改为LEFT JOIN并包含所有内容 –

-1

早期的答案的工作,但都非常缓慢。该查询过去需要15-20分钟才能运行。这个由朋友建议的运行速度要快得多(相同数据集约4秒)。

SELECT users.id, 
     users.email, 
     users.name, 
     users.sid, 
     users.created_at, 
     (CASE 
      WHEN fb_auth > 0 
      THEN 'true' 
      ELSE 'false' 
     END) AS facebook 
FROM users 
     LEFT JOIN (SELECT authentications.user_id, 
         Count(authentications.provider) fb_auth 
        FROM authentications 
        WHERE provider = 'facebook' 
        GROUP BY user_id) auths 
       ON (users.id = auths.user_id) 
GROUP BY users.id, 
      users.email, 
      users.name, 
      users.sid, 
      users.created_at;