Mysql 返回连接表不正确值的行数
Mysql row count returning incorrect values for joined tables
大家好。我正在努力从 tables 的数据库中检索数据。
我的查询如下所示。
SELECT DISTINCT applicable_areas.area, applicable_areas.id as id, count(distinct supreme_applicable_areas.applicable_area_id) as supreme_court_cases, count(distinct appeal_applicable_areas.applicable_area_id) as appeal_court_cases
FROM `applicable_areas`
JOIN appeal_applicable_areas ON appeal_applicable_areas.applicable_area_id = applicable_areas.id
JOIN supreme_applicable_areas ON supreme_applicable_areas.applicable_area_id = applicable_areas.id
JOIN cp_cases_counsel ON ( (cp_cases_counsel.suitno = supreme_applicable_areas.suitno) OR (cp_cases_counsel.suitno = appeal_applicable_areas.suitno))
WHERE cp_cases_counsel.counsel_id = 54
GROUP BY applicable_areas.area, applicable_areas.id
ORDER BY applicable_areas.area ASC;
它似乎检查 'supreme_applicable_areas' table 中是否出现值,如果找到,则继续检查 'appeal_applicable_areas' table 中的值.所以,如果没有supreme的价值,但是有上诉的价值,它带来了supreme和上诉的结果。但是我希望它选择一个。
有办法实现吗?
提前致谢
根据提供的详细信息,这是一个猜测。
此解决方案通过为这种情况推导出稍微更好的结构来避免 JOIN
问题,其中上诉和最高适用区域合并为一个 table,每种类型都有一个指示列, (1, null) 或 (null, 1) 允许在没有条件逻辑的情况下进行计数。分别计算每种类型(stype
和 atype
)时,空值将被忽略。
这可以通过几种不同的方式来完成。这是一个。
SQL(对于MySQL8.0+):
WITH area_types (atype, stype, applicable_area_id, suitno) AS (
SELECT 1, null, applicable_area_id, suitno FROM appeal_applicable_areas
UNION
SELECT null, 1, applicable_area_id, suitno FROM supreme_applicable_areas
)
SELECT applicable_areas.area
, applicable_areas.id as id
, count(stype) as supreme_court_cases
, count(atype) as appeal_court_cases
FROM applicable_areas
JOIN area_types
ON area_types.applicable_area_id = applicable_areas.id
JOIN cp_cases_counsel
ON cp_cases_counsel.suitno = area_types.suitno
WHERE cp_cases_counsel.councel_id = 54
GROUP BY applicable_areas.id
ORDER BY applicable_areas.area ASC
;
并且因为我将 id
设为 applicable_areas
的 primary key
,我们真的不需要 GROUP BY
条款中的 area
(参见:functional dependence
).我已经删除了它。
对于 8.0 之前的 MySQL:
SELECT applicable_areas.area
, applicable_areas.id as id
, count(stype) as supreme_court_cases
, count(atype) as appeal_court_cases
FROM applicable_areas
JOIN (
SELECT 1 AS atype, null AS stype, applicable_area_id, suitno FROM appeal_applicable_areas
UNION
SELECT null , 1 , applicable_area_id, suitno FROM supreme_applicable_areas
) AS area_types
ON area_types.applicable_area_id = applicable_areas.id
JOIN cp_cases_counsel
ON cp_cases_counsel.suitno = area_types.suitno
WHERE cp_cases_counsel.councel_id = 54
GROUP BY applicable_areas.id
ORDER BY applicable_areas.area ASC
;
给定一些随机数据的结果:
+------+----+---------------------+--------------------+
| area | id | supreme_court_cases | appeal_court_cases |
+------+----+---------------------+--------------------+
| 1001 | 1 | 1 | 1 |
| 1002 | 2 | 1 | 1 |
| 1003 | 3 | 0 | 1 |
| 1004 | 4 | 0 | 2 |
| 1005 | 5 | 1 | 0 |
| 1006 | 6 | 1 | 0 |
| 1007 | 7 | 3 | 0 |
+------+----+---------------------+--------------------+
设置:
CREATE TABLE applicable_areas (id int primary key auto_increment, area int);
CREATE TABLE appeal_applicable_areas (applicable_area_id int, suitno int);
CREATE TABLE supreme_applicable_areas(applicable_area_id int, suitno int);
CREATE TABLE cp_cases_counsel (suitno int, councel_id int);
INSERT INTO applicable_areas (area) VALUES
( 1001)
, ( 1002)
, ( 1003)
, ( 1004)
, ( 1005)
, ( 1006)
, ( 1007)
;
INSERT INTO appeal_applicable_areas (applicable_area_id, suitno) VALUES
( 1, 2001)
, ( 2, 2002)
, ( 3, 2003)
, ( 4, 2004)
, ( 4, 2009)
, ( 4, 2010)
;
INSERT INTO supreme_applicable_areas (applicable_area_id, suitno) VALUES
( 1, 3001)
, ( 2, 3002)
, ( 5, 3003)
, ( 6, 3004)
, ( 7, 3005)
, ( 7, 3006)
, ( 7, 3007)
, ( 7, 3008)
;
INSERT INTO cp_cases_counsel (suitno, councel_id) VALUES
( 2001, 54)
, ( 2002, 54)
, ( 2003, 54)
, ( 2004, 55)
, ( 2008, 54)
, ( 2009, 54)
, ( 2010, 54)
, ( 3001, 54)
, ( 3002, 54)
, ( 3003, 54)
, ( 3004, 54)
, ( 3005, 66)
, ( 3006, 54)
, ( 3007, 54)
, ( 3008, 54)
, ( 3009, 54)
, ( 3010, 54)
;
大家好。我正在努力从 tables 的数据库中检索数据。
我的查询如下所示。
SELECT DISTINCT applicable_areas.area, applicable_areas.id as id, count(distinct supreme_applicable_areas.applicable_area_id) as supreme_court_cases, count(distinct appeal_applicable_areas.applicable_area_id) as appeal_court_cases
FROM `applicable_areas`
JOIN appeal_applicable_areas ON appeal_applicable_areas.applicable_area_id = applicable_areas.id
JOIN supreme_applicable_areas ON supreme_applicable_areas.applicable_area_id = applicable_areas.id
JOIN cp_cases_counsel ON ( (cp_cases_counsel.suitno = supreme_applicable_areas.suitno) OR (cp_cases_counsel.suitno = appeal_applicable_areas.suitno))
WHERE cp_cases_counsel.counsel_id = 54
GROUP BY applicable_areas.area, applicable_areas.id
ORDER BY applicable_areas.area ASC;
它似乎检查 'supreme_applicable_areas' table 中是否出现值,如果找到,则继续检查 'appeal_applicable_areas' table 中的值.所以,如果没有supreme的价值,但是有上诉的价值,它带来了supreme和上诉的结果。但是我希望它选择一个。
有办法实现吗?
提前致谢
根据提供的详细信息,这是一个猜测。
此解决方案通过为这种情况推导出稍微更好的结构来避免 JOIN
问题,其中上诉和最高适用区域合并为一个 table,每种类型都有一个指示列, (1, null) 或 (null, 1) 允许在没有条件逻辑的情况下进行计数。分别计算每种类型(stype
和 atype
)时,空值将被忽略。
这可以通过几种不同的方式来完成。这是一个。
SQL(对于MySQL8.0+):
WITH area_types (atype, stype, applicable_area_id, suitno) AS (
SELECT 1, null, applicable_area_id, suitno FROM appeal_applicable_areas
UNION
SELECT null, 1, applicable_area_id, suitno FROM supreme_applicable_areas
)
SELECT applicable_areas.area
, applicable_areas.id as id
, count(stype) as supreme_court_cases
, count(atype) as appeal_court_cases
FROM applicable_areas
JOIN area_types
ON area_types.applicable_area_id = applicable_areas.id
JOIN cp_cases_counsel
ON cp_cases_counsel.suitno = area_types.suitno
WHERE cp_cases_counsel.councel_id = 54
GROUP BY applicable_areas.id
ORDER BY applicable_areas.area ASC
;
并且因为我将 id
设为 applicable_areas
的 primary key
,我们真的不需要 GROUP BY
条款中的 area
(参见:functional dependence
).我已经删除了它。
对于 8.0 之前的 MySQL:
SELECT applicable_areas.area
, applicable_areas.id as id
, count(stype) as supreme_court_cases
, count(atype) as appeal_court_cases
FROM applicable_areas
JOIN (
SELECT 1 AS atype, null AS stype, applicable_area_id, suitno FROM appeal_applicable_areas
UNION
SELECT null , 1 , applicable_area_id, suitno FROM supreme_applicable_areas
) AS area_types
ON area_types.applicable_area_id = applicable_areas.id
JOIN cp_cases_counsel
ON cp_cases_counsel.suitno = area_types.suitno
WHERE cp_cases_counsel.councel_id = 54
GROUP BY applicable_areas.id
ORDER BY applicable_areas.area ASC
;
给定一些随机数据的结果:
+------+----+---------------------+--------------------+
| area | id | supreme_court_cases | appeal_court_cases |
+------+----+---------------------+--------------------+
| 1001 | 1 | 1 | 1 |
| 1002 | 2 | 1 | 1 |
| 1003 | 3 | 0 | 1 |
| 1004 | 4 | 0 | 2 |
| 1005 | 5 | 1 | 0 |
| 1006 | 6 | 1 | 0 |
| 1007 | 7 | 3 | 0 |
+------+----+---------------------+--------------------+
设置:
CREATE TABLE applicable_areas (id int primary key auto_increment, area int);
CREATE TABLE appeal_applicable_areas (applicable_area_id int, suitno int);
CREATE TABLE supreme_applicable_areas(applicable_area_id int, suitno int);
CREATE TABLE cp_cases_counsel (suitno int, councel_id int);
INSERT INTO applicable_areas (area) VALUES
( 1001)
, ( 1002)
, ( 1003)
, ( 1004)
, ( 1005)
, ( 1006)
, ( 1007)
;
INSERT INTO appeal_applicable_areas (applicable_area_id, suitno) VALUES
( 1, 2001)
, ( 2, 2002)
, ( 3, 2003)
, ( 4, 2004)
, ( 4, 2009)
, ( 4, 2010)
;
INSERT INTO supreme_applicable_areas (applicable_area_id, suitno) VALUES
( 1, 3001)
, ( 2, 3002)
, ( 5, 3003)
, ( 6, 3004)
, ( 7, 3005)
, ( 7, 3006)
, ( 7, 3007)
, ( 7, 3008)
;
INSERT INTO cp_cases_counsel (suitno, councel_id) VALUES
( 2001, 54)
, ( 2002, 54)
, ( 2003, 54)
, ( 2004, 55)
, ( 2008, 54)
, ( 2009, 54)
, ( 2010, 54)
, ( 3001, 54)
, ( 3002, 54)
, ( 3003, 54)
, ( 3004, 54)
, ( 3005, 66)
, ( 3006, 54)
, ( 3007, 54)
, ( 3008, 54)
, ( 3009, 54)
, ( 3010, 54)
;