如何解构 COUNT()?

Posted

技术标签:

【中文标题】如何解构 COUNT()?【英文标题】:how do I deconstruct COUNT()? 【发布时间】:2010-05-21 14:33:46 【问题描述】:

我有一个包含一些连接的视图。我正在使用 COUNT(*) 作为选择的列之一从该视图中进行选择。我对它返回的数字感到惊讶。请注意,查询所依据的源视图中没有 GROUP BY 或聚合列语句。

我怎样才能把它拆开来看看它是怎么得出这个数字的?我在GROUP BY 子句中有三列。

SELECT column1, column2, column3, COUNT(*) FROM View GROUP BY column1, column2, column3

我得到类似的结果

+---------+---------+---------+----------+
| column1 | column2 | column3 | COUNT(*) |
+---------+---------+---------+----------+
| value1  | valueA  | value_a |      103 |
+---------+---------+---------+----------+
| value2  | valueB  | value_b |       56 |
+---------+---------+---------+----------+
etc.

我想看看它是如何到达 103、26 等的。换句话说,我想运行一个返回 103 行的查询,以便我知道我已经正确地表达了查询。我正在仔细检查我的工作。

我并不是说我认为 COUNT(*) 不起作用(我知道“SELECT 没有损坏”),我要仔细检查的正是我在查询中表达的内容,因为我想我表达了错误的东西,这就是为什么我会得到意想不到的价值。我需要了解更多我实际指导 mysql 计数的内容。

所以我应该一个一个地把它们拿来,并在 WHERE 子句中尝试每个值吗?换句话说,我应该这样做吗

SELECT column1 FROM View WHERE column1 = 'first_grouped_value'
SELECT column1 FROM View WHERE column1 = 'second_grouped_value'
SELECT column2 FROM View WHERE column1 = 'first_grouped_value'
SELECT column2 FROM View WHERE column1 = 'second_grouped_value'

并查看返回的行数与分组结果中的COUNT(*) 值匹配吗?

出于保密原因,我将无法发布任何查询或数据库结构。我所要求的只是一种通用技术来查看 COUNT(*) 实际计数的内容。

【问题讨论】:

小心!随着行数的增加,带有聚合函数的 MySQL 视图(如count())的性能非常差。这是因为使用的视图算法导致许多索引不可用。 视图本身没有聚合列,但我在视图的 SELECT 中使用聚合列。这是个问题吗? 你说视图有count(*) 所以是的,你在视图中使用了一个聚合函数。更多细节在这里***.com/questions/2760475/mysql-view-performance/… 彼得,我没这么说。 “我正在 select from that view 以 COUNT() 作为列之一。”,意思是“count() as 该选择的列之一”。我刚刚编辑了文本以使其更清晰。 啊,好的,我明白了。感谢您清理它。 【参考方案1】:

这个数字有什么让你吃惊的地方?你期待什么?您实际上需要计算什么?

您的计数将是完整分组中的行数。如果您想计算小时数但按年、月和日分组,则为图像。您的计数将是 24,因为这是每年每个月中每天的小时数。

任何这些变化都应该有助于查看分组;

SELECT column1, count(*)
FROM view
GROUP BY column1    

SELECT column2, count(*)
FROM view
GROUP BY column2    

SELECT column3, count(*)
FROM view
GROUP BY column3    

SELECT column1, column2, count(*)
FROM view
GROUP BY column1, column2

SELECT column2, column3, count(*)
FROM view
GROUP BY column2, column3

SELECT column1, column3, count(*)
FROM view
GROUP BY column1, column3

【讨论】:

【参考方案2】:

我怎样才能把它拆开来看看它是怎么得出这个数字的?

运行此查询:

SELECT  column1, column2, column3, COUNT(*) FROM
FROM    (
        /* View definition here */
        SELECT  …
        ) q
GROUP BY
        column1, column2, column3

并将结果与​​您的实际查询返回的结果进行比较。

我所要求的只是一种查看 COUNT(*) 实际计数的通用技术

我有 11 年的 MySQL 经验,我的眼睛看到了一些可怕的事情,但我从来没有看到它不算数,尽管被告知 COUNT(*)

【讨论】:

这正是我现在所拥有的。我想知道的是它是如何到达那些 COUNT(*) 值的。 @user151841: 抱歉,我不太明白你的问题 :) 如果你不信任 MySQL,那么,请自己计算记录,编写一个 php 脚本来分组和数数。顺便说一句,你为什么不相信COUNT(*) 结果?它们是太大了还是太小了? 数字太大。我相信 COUNT 准确地计算了 something。我不相信我在查询中表达的。我需要了解更多我实际指导 MySQL 计数的内容。 @user:将存储的视图替换为内联视图(如帖子所示),并通过添加和删除条件进行调试。【参考方案3】:

这样你应该从第一个聚合中得到 103 行:

select * from View where column1 = 'value1' and column2 = 'valueA' and column3 = 'value_a'

【讨论】:

【参考方案4】:

这会将组显示为前 3 列 + 计数,然后是成员行的所有列(在组内没有特定顺序):

SELECT X.*
       ,View.*
FROM (
    SELECT column1, column2, column3, COUNT(*)
    FROM View
    GROUP BY column1, column2, column3 
) AS X (column1, column2, column3, row_count)
INNER JOIN View
    ON View.column1 = X.column1
    AND View.column2 = X.column2
    AND View.column3 = X.column3
ORDER BY X.column1, X.column2, X.column3, X.row_count DESC

请注意,由于内部连接,NULL 会有一些问题。

【讨论】:

以上是关于如何解构 COUNT()?的主要内容,如果未能解决你的问题,请参考以下文章

打字稿如何进行对象解构赋值

如果一些被解构而另一些没有被解构,如何记录函数的参数(JSDoc)

如何解构道具

如何使用数字键名解构对象?

如何解构一个可组合的?

如何在不切片的情况下解构向量?