简体   繁体   English

MySQL BY之前的COUNT条记录

[英]MySQL COUNT records before GROUP BY

I'm working on a simple query over two tables and I'm trying to count the number of records with the same ID I would have got if I didn't group them. 我正在对两个表进行简单的查询,并且试图计算如果不对它们进行分组,则具有相同ID的记录数。 These are the tables: 这些是表格:

TABLE jobs TABLE职位

id -- type -- user_id -- field_id id-类型-user_id-field_id

1 -- painting -- 53 -- 12 1-绘画-53-12

2 -- reading -- 53 -- 12 2-阅读-53-12

3 -- writing -- 53 -- 12 3-写作-53-12

TABLE activities TABLE活动

id -- is_test -- user_id -- field_id id-is_test-user_id-field_id

7 -- Yes -- 53 -- 12 7-是-53-12

8 -- No -- 53 -- 12 8-否-53-12

With this query I get the single record that I want from the table jobs (painting) because I'm using the GROUP BY clause on the column jobs.id . 通过此查询,我从表jobs (绘画)中获得了我想要的单条记录,因为我在jobs.id列上使用了GROUP BY子句。 If I didn't use the GROUP BY, I would get 2 records because there are 2 matching activities for the same user_id and field_id . 如果我不使用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;

What I'm trying to do is to fetch another column containing the actual number of matching records in the table activities . 我想做的是获取另一个包含表activities实际匹配记录数的列。 Basically I want to get 2 as count of records in activities with the same user_id and field_id . 基本上我想在具有相同user_idfield_id activities获得2作为记录数。

I have tried to select the new column like this: 我试图选择像这样的新列:

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

but this obviously returns 1 rather than 2 for the new column tot_act . 但这显然为新列tot_act返回1而不是2。 Making it count the field activities.is_test did not work either. 让它计算现场activities.is_test .is_test也不起作用。

I was trying to avoid a sub-select . 试图避免进行子选择

Please do not pay attention to the column activities.is_test , I don't care to see if it's set to Yes or No, I just want to count that there is a matching record for Yes and one for No so 2 records in total if I don't group them. 请不要关注activities.is_test列,我不在乎是否将其设置为Yes或No,我只想计算是否存在与Yes匹配的记录,而对于No则有一个记录,因此总共有2条记录我不分组。 2 is the value I'm trying to retrieve as a new column. 2是我尝试作为新列检索的值

Any ideas will be much appreciated! 任何想法将不胜感激!

Your first query doesn't make any sense. 您的第一个查询没有任何意义。 Group by only has meaning combined with an aggregate function in the output columns (select clause). “分组依据”仅在输出列(选择子句)中与集合函数结合使用。

The where filter on activities.field_id is (expensively) converting the left join into an inner join. activity.field_id上的where过滤器(昂贵地)将左联接转换为内部联接。

I also suspect your schema is not normalised. 我还怀疑您的架构未规范化。

to fetch another column containing the actual number of matching records in the table activities 获取另一个包含表活动中实际匹配记录数的列

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;

COUNT() increments by 1 for each NON NULL value it encounters. COUNT()对于遇到的每个NON NULL值都增加1。

In your case you want the count of rows from the activities table, not the jobs table. 在您的情况下,您需要活动表而不是作业表中的行数。

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;

from your sample data that query produces this result: 从查询的样本数据中得出以下结果:

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

Note however that if you include activity.is_test in the select and grouping clauses then you will not get a count of 2. 但是请注意,如果在select和grouping子句中包含activity.is_test,则计数不会为2。

see this sqlfiddle 看到这个sqlfiddle

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM