【问题标题】:MySQL COUNT records before GROUP BYGROUP BY 之前的 MySQL COUNT 记录
【发布时间】:2016-04-03 23:18:36
【问题描述】:

我正在对两个表进行一个简单的查询,并且我正在尝试计算如果我没有对它们进行分组,我会得到的具有相同 ID 的记录的数量。 这些是表格:

表格作业

id -- type -- user_id -- field_id

1 -- 绘画 -- 53 -- 12

2 -- 读数 -- 53 -- 12

3 -- 写作 -- 53 -- 12

表活动

id -- is_test -- user_id -- field_id

7 -- 是 -- 53 -- 12

8 -- 否 -- 53 -- 12

通过这个查询,我从表jobs(绘画)中得到了我想要的单个记录,因为我在jobs.id 列上使用了GROUP BY 子句。如果我不使用 GROUP BY,我会得到 2 条记录,因为同一 user_idfield_id 有 2 个匹配活动。

SELECT `jobs`.*,`activities`.`is_test` 
FROM `jobs` 
LEFT JOIN `activities` ON `activities`.`user_id`=`jobs`.`user_id` 
WHERE `jobs`.`field_id`=12 AND `activities`.`field_id`=12 AND `jobs`.`type`='painting' AND `jobs`.`user_id`=53 
GROUP BY `jobs`.`id` 
ORDER BY `jobs`.`id` DESC;

我要做的是获取另一列,其中包含表activities 中匹配记录的实际数量。基本上我想在activities 中使用相同的user_idfield_id 获得2 作为记录数。

我尝试像这样选择新列:

SELECT `jobs`.*,`activities`.`is_test`, COUNT(DISTINCT `jobs`.`id`) AS `tot_act` 

但这显然会为新列tot_act 返回 1 而不是 2。使其计数字段activities.is_test 也不起作用。

试图避免子选择

请不要关注activities.is_test栏目,我不关心是否设置为是或否,我只想计算有一个匹配记录是和一个匹配的记录没有所以2记录如果我不将它们分组,则总共。 2 是我尝试检索的值作为新列。

任何想法将不胜感激!

【问题讨论】:

  • 你能澄清一下你想要做什么吗?这里有很多信息,我认为您的请求被困在所有信息的中间。
  • 首先,不要使用select jobs.* 和group by。 MySQL 可能允许您选择不属于聚合或分组依据的列,但其他人很少这样做。此外,您说您在第一个查询中获得 1 条记录,因为您在 jobs.id 上进行分组。根据您的示例数据,我看不出这是怎么可能的,因为您正在选择具有 2 个不同 id 的 2 行
  • 对不起,我会尽量澄清。鉴于我正在使用的查询,我想检索 ID 为 1 的表 jobs 的所有记录,因为类型是 painting。然后我想要activities 表中的两个匹配列之一is_test,因为我不在乎它是哪条记录,只要user_idfield_id 匹配。最后我想得到一个计数列为 2,因为 2 是表 activities 中的匹配记录。感谢您的帮助。
  • 您能否澄清您对is_test 专栏的陈述。是否要显示一个显示为 yesno 的列并且您不在乎它是哪一列?
  • @Lock:谢谢,我不在乎is_test这列是Yes还是No,我只想知道有2条记录。很快就会尝试您的解决方案。再次感谢

标签: mysql select count group-by distinct


【解决方案1】:

COUNT() 每遇到一个 NON NULL 值就加 1。

在您的情况下,您需要活动表中的行数,而不是作业表。

SELECT
      jobs.id
    , jobs.type
    , jobs.user_id
    , Jobs.field_id
    , COUNT(activities.id) activity_count
FROM jobs
      LEFT JOIN activities ON jobs.user_id = activities.user_id
                  AND activities.field_id = 12
WHERE jobs.field_id = 12
      AND jobs.type = 'painting'
      AND jobs.user_id = 53
GROUP BY
      jobs.id
    , jobs.type
    , jobs.user_id
    , Jobs.field_id
ORDER BY
      jobs.id DESC;

从您的示例数据中查询会产生以下结果:

| id |     type | user_id | field_id | activity_count |
|----|----------|---------|----------|----------------|
|  1 | painting |      53 |       12 |              2 |

但是请注意,如果您在 select 和 grouping 子句中包含 activity.is_test,那么您将不会得到 2。

this sqlfiddle

【讨论】:

  • 谢谢,这也很好用,但我无法获取所需的 is_test 字段。
  • 如前所述,如果您在 select 和 group by 子句中包含 activity.is_test,则计数不会是 2。
【解决方案2】:

您的第一个查询没有任何意义。 Group by 仅具有与输出列中的聚合函数结合的含义(选择子句)。

activity.field_id 上的 where 过滤器(昂贵地)将左连接转换为内连接。

我还怀疑您的架构没有标准化。

获取包含表活动中匹配记录的实际数量的另一列

SELECT `jobs`.id, jobs.type, jobs.user_id, 
  Jobs.field_id,`activities`.`is_test`, 
  SUM(IF(activities.id IS NULL, 0,1)) 
FROM `jobs` 
 LEFT JOIN `activities` 
 ON `activities`.`user_id`=`jobs`.`user_id` 
 AND activities.field_id=12
WHERE `jobs`.`field_id`=12 
 AND `jobs`.`type`='painting' 
 AND `jobs`.`user_id`=53 
GROUP BY `jobs`.id, jobs.type, jobs.user_id, 
  Jobs.field_id,`activities`.`is_test`
ORDER BY `jobs`.`id` DESC;

【讨论】:

  • 谢谢你这工作正常。其他解决方案不允许我获取 is_test 字段。我的“是”/“否”示例令人困惑。感谢您让我注意到 where 子句中的 field_id 过滤器正在将左连接转换为内连接。
【解决方案3】:
SELECT
  `jobs`.id,
  `jobs`.type,
  `jobs`.user_id,
  `jobs`.field_id,
  count(1) as activities_count,
  max(`activities`.is_test) as is_test
FROM
  `jobs`
LEFT OUTER JOIN
  `activities` ON
  `activities`.user_id = `jobs`.user_id
  AND `activities`.field_id = `jobs`.field_id
WHERE
  `jobs`.field_id = 12
  AND `jobs`.type = 'painting'
  AND `jobs`.user_id = 53
GROUP BY
  `jobs`.id,
  `jobs`.type,
  `jobs`.user_id,
  `jobs`.field_id

【讨论】:

    猜你喜欢
    • 2016-11-10
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    • 2012-05-06
    • 2016-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多