Mysql 行计数为连接表返回不正确的值[关闭]

Posted

技术标签:

【中文标题】Mysql 行计数为连接表返回不正确的值[关闭]【英文标题】:Mysql row count returning incorrect values for joined tables [closed] 【发布时间】:2021-10-17 20:34:14 【问题描述】:

大家好。我正在跨一些表从数据库中检索数据。

我的查询如下所示。

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”表中值的出现,如果找到,则继续检查“appeal_applicable_areas”表中的值。所以,如果没有至高无上的价值,但有诉求,那么至高和诉求都会带来结果。但是我希望它选择其中一个。

有没有办法做到这一点?

提前致谢

【问题讨论】:

请提供相关架构定义、示例数据、预期结果。如果没有这些东西,我们将在很大程度上进行猜测。谢谢。 首先,结果是什么:SELECT version(); 接下来,你的SQL显然不代表你的要求。看来你一直在尝试“东西”来“得到正确的答案”。你能描述一下你想要获得的两个不同的counts 吗?把事情简单化。现在,您的 SQL 可能会为每个组生成 1,因为您有 COUNT(DISTINCT group_by_term)。这不可能是正确的。 【参考方案1】:

Fiddle

根据提供的详细信息,这是一个猜测。

此解决方案通过为这种情况推导出一个稍微更好的结构来避免JOIN 问题,其中上诉和最高适用领域组合在一个表中,每种类型都有一个指示符列,(1, null) 或 (null , 1) 允许在没有条件逻辑的情况下进行计数。分别计算每种类型(stypeatype)时,只会忽略空值。

这可以通过几种不同的方式完成。这是一个。

SQL(适用于 MySQL 8.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_areasprimary 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)
;

【讨论】:

非常感谢乔恩。我很欣赏这个。成功了 @Korlahwarleh 当然,您现在可以一次处理多个councel,在不同的组中生成它们的计数。只需将councel_id 添加到GROUP BYSELECT 列表和ORDER BY 子句中即可。

以上是关于Mysql 行计数为连接表返回不正确的值[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Mongo Spark 连接器为查询返回不同且不正确的计数?

mysql - 按不存在的值分组

结合连接和计数的MySQL语句?

CI MySQL查询连接表和where语句不返回所有行

计算联接表中的行,但如果不存在行则显示 0 - mysql

TSQL:外部连接表的计数产生不正确的结果