我有两个表,users表包含我系统中的所有用户,另一个表叫做action,其中包含我系统中用户完成的所有操作,我想得到的是一个查询,我可以通过用户,如果我没有为一个用户做任何操作,则获得0。
我的两张桌子:
Users Table:
Name Place
----------------------
James Supermarket
Alex Bank
Ignatius BookShop
Action table:
Name Action
--------------------
James Buy
James Buy
Alex Complaint
Alex Buy
Alex Buy
我想要这样的事情:
Name Transactions Place
-------------------------------
James 2 Supermarket
Alex 3 Bank
Ignatius 0 BookShop
我试过:
SELECT users.name,
(SELECT Count(action.name)
FROM action,
users
WHERE action.name = users.name
GROUP BY action.name)
users.place
FROM
action,
users
WHERE action.name = users.name
但总是给我这个错误:
错误:用作表达式的子查询返回多行 SQL状态:21000
关于如何做的任何想法?
答案 0 :(得分:2)
您应首先进行左连接,然后将group by应用于其结果:
SELECT
u.name
, COUNT(a.name) AS Transactions
, u.place
FROM users u
LEFT OUTER JOIN action a ON a.name = u.name
GROUP BY u.name, u.place
左连接确保即使在action
表中没有关联的事务,也不会丢弃用户记录。
答案 1 :(得分:1)
从不在FROM
子句中使用逗号。始终使用正确的,明确的JOIN
语法。也就是说,如果要使用相关子查询,则不需要对此查询进行任何连接:
SELECT u.name,
(SELECT Count(*)
FROM action a
WHERE a.name = u.name
) as cnt,
u.place
FROM users u;
对于性能,您需要action(name)
上的索引。使用此类索引,这可能比使用left join
和group by
的其他版本更快。
注意:
group by
。where
子句。答案 2 :(得分:1)
与之前的回答一样,左连接会让你看到。 如果要在结果中包含位置,请在汇总后执行左连接
SELECT a.name,
ISNULL(b.cnt, 0) AS Transactions,
a.place
FROM users a
LEFT JOIN
(SELECT name,
Count(name) cnt
FROM action
GROUP BY name) b
ON a.name = b.name