5

我在 SQL(MySQL) 中的数据导入脚本中遇到问题,我需要按类型对行进行分组以计算每种类型有多少行。到目前为止,这并不是一个真正的问题,因为我知道我可以做到:

SELECT 
  data.type, 
  COUNT(data.type) 
FROM data 
GROUP BY data.type;

因此,通过这样做,我得到了结果:

-------------- ---------
| 类型 | 计数(数据类型)|
|--------------|----------|
| 0 | 1 |
| 1 | 46 |
| 2 | 35 |
| 3 | 423 |
| 4 | 64 |
| 5 | 36 |
| 9 | 1 |
 -------------- ---------

我知道在类型列中,值将始终在 0 到 9 的范围内,就像上面的结果一样。因此,我不仅想列出表内容中的现有值,还想列出缺失的类型值,并将它们的 COUNT 值设置为 0。

根据上述查询结果,预期结果为:

-------------- ---------
| 类型 | 计数(数据类型)|
|--------------|----------|
| 0 | 1 |
| 1 | 46 |
| 2 | 35 |
| 3 | 423 |
| 4 | 64 |
| 5 | 36 |
| 6 | 0 |
| 7 | 0 |
| 8 | 0 |
| 9 | 1 |
 -------------- ---------

我可以在 GROUP/COUNT-1 表内容之前巧妙地插入每种类型的一行,在 INSERT 上标记其他列以便能够在之后删除这些行。因此,我的导入脚本的步骤将更改为:

  1. TRUNCATE表;(如果表中有旧数据,我无法安全导入新内容)
  2. 插入“控制”行;
  3. 将数据文件加载到表中
  4. GROUP/COUNT-1表格内容;
  5. 删除“控制”行;(所以我仍然可以使用表格内容)
  6. 做任何其他工作

但是,我正在寻找一种更清洁的方法来达到预期的结果。如果可能,单个查询,没有一堆 JOIN。

我将不胜感激任何建议或意见。非常感谢你!

编辑

我要感谢有关创建表以存储所有类型以加入它的答案。它确实解决了问题。我的方法也解决了它,但它是否像您一样存储类型。

所以,我有“另一个”问题,只是一个澄清,基于收到的答案和我想要的范围......是否有可能使用一些不会创建新表和/或插入这些类型的 MySQL 命令达到预期结果?

实际上,在解决存储类型的问题时,我看不到任何问题...我只想找到一个简化的命令...类似于“最佳实践”...某种过滤器...作为我可以运行:

GROUP BY data.type(0,1,2,3,4,5,6,7,8,9)

它可以返回这些过滤后的值。

如果它真的存在/可能的话,我真的很想学习这样的命令。

再次,非常感谢您!

4

4 回答 4

0

假设您有一个types包含所有有效类型的表:

SELECT t.type, 
       COUNT(data.type) 
FROM data join types t on data.type = t.type
GROUP BY t.type
order by t.type

您应该包括显式order by而不是依赖于group by以特定顺序产生结果。

于 2013-01-14T17:28:24.017 回答
0

最简单的方法是创建一个包含所有type值的表,然后在获取计数时加入该表:

select t.type,
  count(d.type)
from types t
left join data d
  on t.type = d.type
group by t.type

请参阅带有演示的 SQL Fiddle

或者,您可以使用以下内容:

select t.type,
  count(d.type)
from
(
  select 0 type
  union all
  select 1 
  union all
  select 2
  union all
  select 3
  union all
  select 4
  union all
  select 5 
  union all
  select 6
  union all
  select 7
  union all
  select 8
  union all
  select 9 
) t
left join data d
  on t.type = d.type
group by t.type

请参阅带有演示的 SQL Fiddle

于 2013-01-14T17:28:59.397 回答
0

一种选择是使用值为 0-9 的静态数字表。不确定这是否是最优雅的方法,如果您使用的是 SQL Server,我可以考虑另一种方法。

尝试这样的事情:

SELECT 
  numbers.number, 
  COUNT(data.type) 
FROM numbers 
left join data 
  on numbers.number = data.type
GROUP BY numbers.number;

还有SQL 小提琴

于 2013-01-14T17:32:34.180 回答
0

好吧...我想我找到了!谢谢你们!!!我接受我自己的答案。

我同意@GordonLinoff 评论,即最佳实践是指存储类型值并描述它们,因此您可以保持简洁/可理解的数据库和查询。

但是,据我所知,如果您有一些可能是无关信息的数据,最好以其他方式处理它而不是存储它。

所以,我开发了这个查询:

SELECT 
  SUM(IF(data.type = 0, 1, 0)) AS `0`, 
  SUM(IF(data.type = 1, 1, 0)) AS `1`, 
  SUM(IF(data.type = 2, 1, 0)) AS `2`, 
  SUM(IF(data.type = 3, 1, 0)) AS `3`, 
  SUM(IF(data.type = 4, 1, 0)) AS `4`, 
  SUM(IF(data.type = 5, 1, 0)) AS `5`, 
  SUM(IF(data.type = 6, 1, 0)) AS `6`, 
  SUM(IF(data.type = 7, 1, 0)) AS `7`, 
  SUM(IF(data.type = 8, 1, 0)) AS `8`, 
  SUM(IF(data.type = 9, 1, 0)) AS `9` 
FROM data;

不是一个更快、优化和美观的查询,但对于我将管理的数据大小(每次导入少于 100.000 行),它“手动”执行 GROUP/COUNT 工作,在普通开发人员机器上运行 0.13 秒。

它与我的预期结果不同,只是在选择行和列的方式上——而不是 10 行和 2 列,我有 1 行和 10 列,标有匹配类型。此外,由于我们对类型值进行了标准化(并且我们肯定不会更改它),它给它一个名称和描述,我现在可以使用类型名称作为列标签,而不是加入到带有类型信息的表以在结果中选择第三列(这实际上并不重要,因为它是基于某些标准的导入脚本)。

非常感谢大家的帮助!

于 2015-12-22T17:15:30.910 回答