1

我认为从我拥有的表格和我想要的结果开始是最容易的。

Name | Date
A    | 03/01/2012
A    | 03/01/2012
B    | 02/01/2012
A    | 02/01/2012
B    | 02/01/2012
A    | 02/01/2012
B    | 01/01/2012
B    | 01/01/2012
A    | 01/01/2012

我希望我的查询结果是:

Name | 01/01/2012 | 02/01/2012 | 03/01/2012
A    |     1      |     2      |     2
B    |     2      |     2      |     0

所以基本上我想计算具有相同日期的行数,但是对于每个单独的名称。所以一个简单的按日期分组是行不通的,因为它会将名称合并在一起。然后我想输出一个表格,使用 php 显示每个日期的计数。

我已经看到答案建议是这样的:

SELECT
  NAME,
  SUM(CASE WHEN GRADE = 1 THEN 1 ELSE 0 END) AS GRADE1,
  SUM(CASE WHEN GRADE = 2 THEN 1 ELSE 0 END) AS GRADE2,
  SUM(CASE WHEN GRADE = 3 THEN 1 ELSE 0 END) AS GRADE3
FROM Rodzaj
GROUP BY NAME

所以我想我会有一种方法来调整它,但我想知道是否有另一种方法,或者那是最有效的?我可能在想,如果 while 循环每次只输出一个特定的名称和日期以及计数,那么第一个结果将是 A,01/01/2012,1 然后是下一个 A,02/01/2012, 2 - A,03/01/2012,3 - B,01/01/2012,2 等,那么也许这可以通过不同的技术实现,但不确定这样的事情是否可行以及是否有效。

所以我基本上是想看看是否有人对此有任何不合时宜的想法,以及他们将如何进行比较。

我希望我能很好地解释一切,并提前感谢您的帮助。

4

3 回答 3

2

您必须在您的 中包含两列GROUP BY

SELECT   name, COUNT(*) AS count
FROM     your_table
GROUP BY name, date

这将以行格式获取每个名称 -> 日期组合的计数。0如果名称在特定日期没有任何行,您还想包含计数,您可以使用:

SELECT     a.name,
           b.date,
           COUNT(c.name) AS date_count
FROM       (SELECT DISTINCT name FROM your_table) a
CROSS JOIN (SELECT DISTINCT date FROM your_table) b
LEFT JOIN  your_table c ON a.name = c.name AND 
                           b.date = c.date
GROUP BY   a.name, 
           b.date

SQLFiddle 演示

于 2012-08-04T19:15:41.437 回答
2

你要求一个“支点”。基本上,它就是这样。数据透视的真正问题是列必须适应数据,而单独使用 SQL 是不可能做到的。

这是你如何做到的:

SELECT
  Name,
  SUM(`Date` = '01/01/2012') AS `01/01/2012`,
  SUM(`Date` = '02/01/2012') AS `02/01/2012`,
  SUM(`Date` = '03/01/2012') AS `03/01/2012`
FROM mytable
GROUP BY Name

请注意,您可以在 mysql 中使用一个很酷的方法SUM(),因为在 mysqltrue中 is1falseis 0,因此对条件求和相当于计算它为真的次数。

首先使用内部组并不是更有效。

于 2012-08-04T19:24:22.937 回答
0

以防万一有人对最好的方法感兴趣:

Zane 的第二个建议是最慢的,我加载了我为其他两个所做的数据的三分之一,这花了很长时间。也许在较小的表上它会更有效,虽然我没有使用一个巨大的表,但大约 28,000 行足以造成明显的滞后,而 between 子句将结果降至约 4000 行。

波西米亚人的回答给了我最少的代码,我投入了一个循环来创建所有的案例陈述,它工作起来相对容易。这种方法的好处是简单,除了为案例创建循环外,不需要任何 php 技巧就可以得到结果,只需简单的 foreach 即可获取所有列。推荐给那些对 php 没有信心的人。

然而,我发现 Zane 的第一个建议是最快的,尽管需要额外的 php 编码,但我似乎会坚持使用这种方法。这种方法的缺点是它只给出实际有数据的日期,所以创建一个包含所有日期的表变得有点复杂。我所做的是创建一个变量来跟踪它应该与在每个表行上重置的表列进行比较的日期,当查询的结果等于该日期时,它会回显该值,否则它会执行while 循环用 0 回显表格单元格,直到日期匹配。它还必须检查“名称”值是否仍然相同,如果没有,它会在将任何缺失的单元格填充到该行末尾后切换到下一行。

两种方法的结果超过 3 个月的数据(每天一列,因此大约 90 个案例陈述)~ 28,000 行中的 12,000 行:
Bohemian's Pivot - ~0.158s(最高可见 ~0.36s)
Zane's Double Group by - ~0.086s (最高可见〜0.15s)

于 2012-08-07T18:04:42.243 回答