MySQL 查询的联接表中的 GROUP BY,COUNT()
GROUP BY, COUNT() in joined tables of MySQL query
我希望在一组两个日期内按类别统计我的所有项目。
我有一个主 table:
Table 项目
+-----+-------------+------------------+
| uid | name | project_category |
+-----+-------------+------------------+
| 1 | Testproject | 1 |
| 2 | Anothertest | 2 |
| 3 | Fietspomp | 1 |
| 4 | Caramba | 1 |
+-----+-------------+------------------+
谁的类别存储在project_category
+-----+-------------+
| uid | name |
+-----+-------------+
| 1 | Automotive |
| 2 | Hospitality |
| 3 | Other |
+-----+-------------+
不过,我的日期存储在以下 table 中。每个项目可以有更多日期(班次)。我只想找到每个项目的最早日期(班次):我需要过滤每个项目的开始日期(= 第一个班次)。
Table project_shift
+-----+-------------+------------+
| uid | project_uid | date |
+-----+-------------+------------+
| 1 | 1 | 2015-05-03 |
| 2 | 2 | 2015-05-02 |
| 3 | 2 | 2015-06-04 |
| 4 | 1 | 2015-03-08 |
| 5 | 1 | 2015-08-08 |
+-----+-------------+------------+
我一直在寻找高低,但我的计数总是乱七八糟。这是我试过的:
SELECT pc.name as category, p.name, count(p.uid)
FROM project p
INNER JOIN project_category pc ON pc.uid = p.project_category
INNER JOIN project_shift ps ON ps.project_uid = p.uid AND ps.date BETWEEN "2015-01-01" AND "2015-08-08"
GROUP BY pc.uid
另外:
SELECT pc.name as category, count(pc.uid) as amount
FROM project p
LEFT JOIN project_category pc ON pc.uid = p.project_category
WHERE (SELECT MIN(date) FROM project_shift ps WHERE ps.project_uid = p.uid LIMIT 1) BETWEEN :date_from AND :date_to
GROUP BY pc.uid
最后一个项目很接近,但仍然多了 29 个项目。
我在这里做错了什么?
编辑:所需结果如下(虚拟数据)
+-------------+--------+
| category | amount |
+-------------+--------+
| Automotive | 70 |
| Hospitality | 22 |
| Other | 2 |
+-------------+--------+
试试这个:
SELECT pc.name as category, count(pc.uid) as amount
FROM project p
INNER JOIN project_category pc ON pc.uid = p.project_category
INNER JOIN
(
SELECT MIN(`date`) AS `date`, project_uid FROM project_shift
WHERE `date` BETWEEN :date_from AND :date_to
GROUP BY project_uid
) AS ps ON (ps.project_uid = pc.uid)
GROUP BY pc.uid
您还需要将项目 table 中的 project_category 添加到组中:
SELECT pc.name as category, count(p.project_category)
FROM project p, project_category pc, project_shift ps
where pc.uid = p.project_category
and ps.project_uid = p.uid
and ps.date BETWEEN '1/1/2015' and '8/8/2015'
group by pc.uid, p.project_category
应该做的。
您的查询似乎基本正确。只是,project_category 您应该从中进行选择,并且应该进行外部连接的项目(例如获取项目为零的类别)。因此,您要按类别计算项目(即 p.uid
)。
那么你的 LIMIT 子句就没有意义了。 MIN(date) 为您提供一条记录,其中包含项目的最短日期。这里不需要 LIMIT 子句。
SELECT pc.name as category, count(p.uid) as amount
FROM project_category pc
LEFT JOIN project p ON p.project_category = pc.uid
WHERE (SELECT MIN(date) FROM project_shift ps WHERE ps.project_uid = p.uid)
BETWEEN :date_from AND :date_to
GROUP BY pc.uid;
我希望在一组两个日期内按类别统计我的所有项目。 我有一个主 table:
Table 项目
+-----+-------------+------------------+
| uid | name | project_category |
+-----+-------------+------------------+
| 1 | Testproject | 1 |
| 2 | Anothertest | 2 |
| 3 | Fietspomp | 1 |
| 4 | Caramba | 1 |
+-----+-------------+------------------+
谁的类别存储在project_category
+-----+-------------+
| uid | name |
+-----+-------------+
| 1 | Automotive |
| 2 | Hospitality |
| 3 | Other |
+-----+-------------+
不过,我的日期存储在以下 table 中。每个项目可以有更多日期(班次)。我只想找到每个项目的最早日期(班次):我需要过滤每个项目的开始日期(= 第一个班次)。
Table project_shift
+-----+-------------+------------+
| uid | project_uid | date |
+-----+-------------+------------+
| 1 | 1 | 2015-05-03 |
| 2 | 2 | 2015-05-02 |
| 3 | 2 | 2015-06-04 |
| 4 | 1 | 2015-03-08 |
| 5 | 1 | 2015-08-08 |
+-----+-------------+------------+
我一直在寻找高低,但我的计数总是乱七八糟。这是我试过的:
SELECT pc.name as category, p.name, count(p.uid)
FROM project p
INNER JOIN project_category pc ON pc.uid = p.project_category
INNER JOIN project_shift ps ON ps.project_uid = p.uid AND ps.date BETWEEN "2015-01-01" AND "2015-08-08"
GROUP BY pc.uid
另外:
SELECT pc.name as category, count(pc.uid) as amount
FROM project p
LEFT JOIN project_category pc ON pc.uid = p.project_category
WHERE (SELECT MIN(date) FROM project_shift ps WHERE ps.project_uid = p.uid LIMIT 1) BETWEEN :date_from AND :date_to
GROUP BY pc.uid
最后一个项目很接近,但仍然多了 29 个项目。
我在这里做错了什么?
编辑:所需结果如下(虚拟数据)
+-------------+--------+
| category | amount |
+-------------+--------+
| Automotive | 70 |
| Hospitality | 22 |
| Other | 2 |
+-------------+--------+
试试这个:
SELECT pc.name as category, count(pc.uid) as amount
FROM project p
INNER JOIN project_category pc ON pc.uid = p.project_category
INNER JOIN
(
SELECT MIN(`date`) AS `date`, project_uid FROM project_shift
WHERE `date` BETWEEN :date_from AND :date_to
GROUP BY project_uid
) AS ps ON (ps.project_uid = pc.uid)
GROUP BY pc.uid
您还需要将项目 table 中的 project_category 添加到组中:
SELECT pc.name as category, count(p.project_category)
FROM project p, project_category pc, project_shift ps
where pc.uid = p.project_category
and ps.project_uid = p.uid
and ps.date BETWEEN '1/1/2015' and '8/8/2015'
group by pc.uid, p.project_category
应该做的。
您的查询似乎基本正确。只是,project_category 您应该从中进行选择,并且应该进行外部连接的项目(例如获取项目为零的类别)。因此,您要按类别计算项目(即 p.uid
)。
那么你的 LIMIT 子句就没有意义了。 MIN(date) 为您提供一条记录,其中包含项目的最短日期。这里不需要 LIMIT 子句。
SELECT pc.name as category, count(p.uid) as amount
FROM project_category pc
LEFT JOIN project p ON p.project_category = pc.uid
WHERE (SELECT MIN(date) FROM project_shift ps WHERE ps.project_uid = p.uid)
BETWEEN :date_from AND :date_to
GROUP BY pc.uid;