MySQL - 仅在每个分组值的第一个实例中显示字段值?

时间:2009-05-27 14:25:19

标签: sql mysql dataset group-by grouping

我认为这不可行,但我希望以其他方式证明这一点。

我编写了一个简单的报告查看类来输出各种数据库查询的结果。为了改善显示效果,当我有一个包含分组数据的报表时,我想在每个唯一值的第一行显示字段值 - 我想在查询级别执行此操作,否则它会我的班级需要额外的逻辑来确定这些特殊值。

用一个简单的例子说明我的要求可能会有所帮助。想象一下这个数据集:

Year    Quarter    Total
2008    Q1         20
2008    Q2         25
2008    Q3         35
2008    Q4         40
2009    Q1         15
2009    Q2         20
2009    Q3         30
2009    Q4         35

如果可能,我希望将数据集返回为:

Year    Quarter    Total
2008    Q1         20
        Q2         25
        Q3         35
        Q4         40
2009    Q1         15
        Q2         20
        Q3         30
        Q4         35

有没有办法在MySQL中以编程方式执行此操作?

4 个答案:

答案 0 :(得分:7)

SELECT  CASE WHEN @r = year THEN NULL ELSE year END AS year,
        quarter,
        total,
        @r := year
FROM    (
        SELECT  @r := 0
        ) vars,
        mytable
ORDER BY
        year

@r这是一个会话变量。您可以像MySQL一样在任何过程语言中使用这些变量。

首先,它在子查询中初始化为零。

其次,它在SELECT子句中进行了检查。如果@r的当前值不等于year,则输出year,否则输出NULL

第三,它使用year的当前值进行了更新。

答案 1 :(得分:4)

你为什么要这样做?那么Year列为空或null的现有记录呢?

美化输出属于报告逻辑。在伪代码中它会是......像:

var lastYear = 0
foreach (record in records)
{
   if (record.Year == lastYear)
   {
     print "   "
   }
   else
   {
     print record.Year
     lastYear = record.Year
   }

   // print the other columns
 }

答案 2 :(得分:1)

不是你要求的答案,但......

听起来像是在MySQL中做的一件好事。仅仅看一下数据的原始行,2008年和2009年的第二季度似乎并不像数据行那样有意义。问题是表现性的,而不是获取数据的问题。听起来更像是要写入你的观察类 - 当传递某个参数时,例如,它会知道不要重复像“2008”这样的东西。

这样可以提高代码的可重用性:当你想要以不同的方式呈现数据时,而不是以季度而不是年份来重写查询时,你可以只改变查看类的一个参数,以便具有不同order子句的相同查询可以输出:

Quarter   Year   Total
Q1        2008   20
          2009   15
Q2        2008   25
          2009   20
...

答案 3 :(得分:1)

它与您的请求不完全匹配,但我宁愿转动我的表格。它允许在视觉上比较2年的数字,因为每列有四分之一:

SELECT Year, 
       SUM(IF(Quarter="Q1", Rev, 0)) AS Q1,
       SUM(IF(Quarter="Q2", Rev, 0)) AS Q2, 
       SUM(IF(Quarter="Q3", Rev, 0)) AS Q3, 
       SUM(IF(Quarter="Q4", Rev, 0)) AS Q4 
FROM t1 GROUP BY 1
ORDER BY 1

然后你有:

YEAR Q1   Q2   Q3   Q4
2008
2009