2009-05-27 13 views
2

Je ne pense pas que ce soit possible, mais je voudrais être prouvé autrement.MySQL - Afficher la valeur du champ uniquement en première instance de chaque valeur groupée?

J'ai écrit une classe d'affichage de rapport simple pour afficher les résultats de diverses requêtes de base de données. Dans le but d'améliorer l'affichage, quand j'ai un rapport avec des données groupées, je voudrais afficher la valeur de champ seulement sur la première rangée de chaque valeur unique - et je voudrais le faire au niveau de la requête, ou il serait nécessite une logique supplémentaire dans ma classe pour déterminer ces valeurs spéciales.

Il sera probablement utile d'illustrer mes exigences avec un exemple simple. Imaginez cet ensemble de données:

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 

Si possible, je voudrais l'ensemble de données retourné comme:

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

Est-il possible de le faire progammatically dans MySQL?

Répondre

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 Voici une variable de session. Vous pouvez les utiliser dans MySQL comme n'importe quelle variable dans n'importe quel langage procédural.

D'abord, il est initialisé à zéro dans la sous-requête. Ensuite, il est vérifié dans la clause SELECT. Si la valeur actuelle de @r n'est pas égale à year, le year est généré, sinon NULL est généré. Troisièmement, il est mis à jour avec la valeur actuelle year.

+1

+1 bien que ce soit quelque chose de mieux fait dans le client du rapport: P – Andomar

+0

+1 pour une solution de travail, mais qui nécessite un effort considérable pour la maintenance - plus que la gestion des fonctionnalités de ma classe. Je pense que ce que je vais faire est d'ajouter une valeur au nom de la colonne, pour marquer ma classe pour afficher les données d'une certaine manière. Par exemple, 'Year__FirstGroup'. – BrynJ

+0

@BrynJ: comme le dit @Andomar, cela est bien sûr mieux fait sur le client, mais je ne comprends pas vraiment ce que vous entendez par «effort pour maintenir». Cette requête ne cassera pas étant une fois écrite, il n'y a rien à maintenir ici :) – Quassnoi

4

Pourquoi voudriez-vous faire cela? Qu'en est-il des enregistrements existants où la colonne Année est vide ou nulle?

L'embellissement de la sortie appartient à la logique du rapport. En pseudocode ce serait sth. comme:

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

    // print the other columns 
} 
+0

Oui, je comprends ce que vous dites - je suis à la recherche de la méthode la plus simple à mettre en œuvre/maintenir. S'il y avait une telle solution dans MySQL, peut-être sous la forme d'une fonction telle que GROUP_CONCAT etc, alors ce serait une solution facile et maintenable. – BrynJ

+0

Je pense que ce que je vais faire est d'ajouter une certaine chaîne aux noms de colonnes (au niveau de la requête) que je veux grouper comme ceci. Par exemple: SELECT YEAR (date) AS 'Year__FirstGroup', MONTH (date) AS Month, SUM (peu importe) AS Total FROM mytable GROUP BY Année, Mois – BrynJ

1

pas la réponse que vous avez demandé, mais ...

Sons comme une chose à faire iffy MySQL en premier lieu. En regardant simplement les rangées de données brutes, les Q2 de 2008 et 2009 ne semblent pas avoir beaucoup de sens en tant que lignes de données. Le problème est de présentation, pas d'aller chercher des données. Cela ressemble plus à quelque chose à écrire dans votre classe d'affichage - lorsque vous passez un certain paramètre, par exemple, il ne sait pas répéter des choses comme "2008". Cela permet également une plus grande réutilisabilité du code: plutôt que de réécrire la requête lorsque vous souhaitez présenter les données différemment, disons par trimestres plutôt que par année, vous pouvez simplement modifier l'un des arguments de la classe de visualisation. que la même requête avec une autre sortie peut clause de commande:

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

Je comprends que cela n'a pas beaucoup de sens du point de vue des données - J'espérais juste qu'il y aurait une façon simple de le faire dans mysql avec une fonction intégrée, de la même façon que vous avez GROUP_CONCAT etc. – BrynJ

1

Il ne correspond pas exactement à votre demande, mais je préférerais faire pivoter ma table.Il permet de comparer visuellement les chiffres des 2 ans que vous avez un quart par colonne:

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 

Vous avez alors:

YEAR Q1 Q2 Q3 Q4 
2008 
2009 
Questions connexes