我有以下表格
商业
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| b_id | bigint(20) | NO | PRI | NULL | auto_increment |
| b_name | varchar(255) | NO | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
位置
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| l_id | bigint(20) | NO | PRI | NULL | auto_increment |
| l_name | varchar(255) | NO | | NULL | |
| b_id | big(20) | NO | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
工作
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| j_id | bigint(20) | NO | PRI | NULL | auto_increment |
| j_name | varchar(255) | NO | | NULL | |
| b_id | bigint(20) | NO | | NULL | |
| l_id | bigint(20) | NO | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
人
+-------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------+------+-----+---------+----------------+
| u_id | bigint(20) | NO | PRI | NULL | auto_increment |
| salutation | varchar(10) | NO | | NULL | |
| first_name | varchar(25) | NO | | NULL | |
| last_name | varchar(25) | NO | | NULL | |
+-------------+---------------+------+-----+---------+----------------+
人们的工作
+-------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------+------+-----+---------+----------------+
| pj_id | bigint(20) | NO | PRI | NULL | auto_increment |
| u_id | bigint(20) | NO | | NULL | |
| j_id | bigint(20) | NO | | NULL | |
| l_id | bigint(20) | NO | MUL | NULL | |
+-------------+------------+------+-----+---------+----------------+
我需要制作一个显示
的表格 +----------+-------------------------+------------+------------+------------+
| b_id | b_name | Locations | Jobs | People |
+----------+-------------------------+------------+------------+------------+
| 21 | Widgets Inc | 0 | x | 0 |
| 24 | Prince Privates | 0 | 0 | 0 |
| 23 | Halon plc | x | 0 | 0 |
| 18 | Stinky Hotels | x | x | x |
| 20 | Pylon Catering Corps | x | x | x |
| 22 | Skytrain Biscuits | 0 | 0 | 0 |
+----------+-------------------------+------------+------------+------------+
我可以通过以下方式为每个业务实现正确的匹配位置计数:
SELECT b.b_id,
b.b_name,
count(l.l_id) AS locations
FROM business AS b
LEFT JOIN locations AS l ON b.b_id=l.b_id
GROUP BY b.b_id
ORDER BY b_name
如果我将其扩展到包括每个企业的工作数量,然后计算每个企业的人数,那么这一切都会变成梨形。
我知道以下在获得人数方面本质上是错误的(因为人们可以容纳超过1份工作)。我不知道我是否需要使用子选择或COALESCE?
SELECT b.b_id,
b.b_name,
count(l.l_id) AS locations,
count(j.j_id) AS jobs,
count(p.u_id) AS people
FROM business AS b
LEFT JOIN locations AS l ON b.b_id=l.b_id
LEFT JOIN job AS j ON b.b_id=j.b_id
LEFT JOIN people_jobs AS p ON l.l_id=p.l_id
GROUP BY b.b_id
ORDER BY b_name
答案 0 :(得分:3)
我认为您可以使用count(distinct)
快速修复查询:
SELECT b.b_id, b.b_name,
count(distinct l.l_id) AS locations,
count(distinct j.j_id) AS jobs,
count(distinct p.u_id) AS people
FROM business b LEFT JOIN
locations l
ON b.b_id = l.b_id LEFT JOIN
job j
ON b.b_id = j.b_id LEFT JOIN
people_jobs p
ON l.l_id = p.l_id
GROUP BY b.b_id
ORDER BY b_name ;
问题可能只是join
到people_jobs
需要更多条件:
people_jobs p
ON l.l_id = p.l_id and j.j_id = p.j_id
可能是u
上的条件。
您的问题是,您正尝试跨多个维度进行汇总,并为每个业务获取笛卡尔积。有时需要的替代方法是在子查询中进行计数。
答案 1 :(得分:1)
此查询应该满足您的需求:
SELECT
b.b_id,
b.b_name,
(SELECT COALESCE(COUNT(l_id ),0) FROM locations WHERE b_id=b.b_id) AS locations,
(SELECT COALESCE(COUNT(j_id ),0) FROM jobs WHERE b_id=b.b_id) AS jobs,
(SELECT COALESCE(COUNT(DISTINCT u_id),0)
FROM jobs j
JOIN people_jobs pj ON pj.j_id=j.j_id
WHERE j.b_id=b.b_id
) AS people
FROM business as b
ORDER BY b_name
如果使用subSELECT,则不需要GROUP BY,因为外部查询将每个b_id返回1行,不再有。
如果你在主要查询级别加入4个表,就像你在做的那样,你有两个困难:
(如戈登的回答所示)
答案 2 :(得分:0)
您可以尝试此查询: -
SELECT b.b_id,b.b_name,count(l.l_id) AS locations,count(j.j_id) AS jobs,count(p.u_id) AS people
FROM business as b LEFT JOIN locations as l ON b.b_id=l.b_id
LEFT JOIN job as j ON b.b_id=j.b_id
LEFT JOIN people_jobs as p ON l.l_id=p.l_id
GROUP BY b.b_id, b.b_name
ORDER BY b_name
我希望这对你有用。