MySQL - показывать значение поля только в первом экземпляре каждого сгруппированного значения? - PullRequest
2 голосов
/ 27 мая 2009

Я не думаю, что это возможно, но я бы хотел доказать обратное.

Я написал простой класс просмотра отчетов для вывода результатов различных запросов к базе данных. В целях улучшения отображения, когда у меня есть отчет с сгруппированными данными, я хотел бы отображать значение поля только в первой строке каждого уникального значения - и я хотел бы сделать это на уровне запроса, иначе Мне нужна дополнительная логика в моем классе, чтобы определить эти специальные значения.

Вероятно, это поможет проиллюстрировать мои требования на простом примере. Представьте себе этот набор данных:

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 ]

7 голосов
/ 27 мая 2009
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.

4 голосов
/ 27 мая 2009

Почему вы хотите это сделать? А как насчет существующих записей, где столбец Год пуст или равен нулю?

Украшение вывода принадлежит логике отчета. В псевдокоде это будет что-то. как:

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

   // print the other columns
 }
1 голос
/ 19 августа 2009

Это не совсем соответствует вашему запросу, но я бы предпочел повернуть мою таблицу. Это позволяет визуально сравнивать цифры за 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 
1 голос
/ 27 мая 2009

Не тот ответ, который вы просили, но ...

Похоже, что сначала в MySQL делать глупости. Просто глядя на необработанные строки данных, Q2 2008 и 2009 годов, похоже, не имеют особого смысла в качестве строк данных. Проблема носит презентационный характер, а не в получении данных. Звучит больше как что-то, что будет записано в ваш класс просмотра - например, при передаче определенного параметра он будет знать, что не следует повторять такие вещи, как «2008».

Это также обеспечивает большую возможность повторного использования кода: вместо того, чтобы переписывать запрос, когда вы хотите представить данные по-другому, скажем, по кварталам, а не по году, вы можете просто изменить один из аргументов класса просмотра так, чтобы один и тот же запрос с другим предложением порядка может вывести:

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