2013-02-20 3 views
3

je n'ai pas null une base de données:groupe par des valeurs

+--+----+---------+ 
|id|name|source_id| 
+--+----+---------+ 
|11|aaaa|null 
+--+----+---------+ 
|12|bbbb|1 
+--+----+---------+ 
|13|cccc|1 
+--+----+---------+ 
|14|dddd|null 
+--+----+---------+ 
|15|eeee|2 
+--+----+---------+ 
|16|ffff|2 
+--+----+---------+ 
|17|gggg|2 
+--+----+---------+ 

J'aimerais sélectionner toutes les entrées, avec une exception:

  • toutes les entrées avec source_id == somevalue(not null) doivent être regroupés
  • dernière entrée avec source_id == null devrait exister après

Voici le résultat que je pense:

+----+--+----+---------+ 
COUNT|id|name|source_id| 
+----+--+----+---------+ 
.....|11|aaaa|null 
+----+--+----+---------+ 
.2...|13|cccc|1 
+----+--+----+---------+ 
.....|14|dddd|null 
+----+--+----+---------+ 
.3...|17|ffff|2 
+----+--+----+---------+ 

Jusqu'à présent, je l'ai fait (note: "change_count" = COUNT):

SELECT *, (To_days(date_expires)-TO_DAYS(NOW())) as dayDiff, COUNT(id) AS change_count FROM mytable 
GROUP BY source_id 
HAVING dayDiff < 4 
ORDER BY date_created DESC 

C'est ce que je reçois:

+----+--+----+---------+ 
COUNT|id|name|source_id| 
+----+--+----+---------+ 
.2...|11|aaaa|null 
+----+--+----+---------+ 
.2...|12|bbbb|1 
+----+--+----+---------+ 
.3...|15|eeee|2 
+----+--+----+---------+ 

Comme vous pouvez le voir le résultat a 2 problèmes:

  • entrées sont regroupées par première occurrence source_id (devrait être le dernier (dernier))
  • nulls sont également regroupés (ne doivent pas être regroupés)

est la tâche que je l'ai décrit ci-dessus réalisable? Comment fait-on ça?

Edit:

SELECT *, COUNT(id) AS change_count FROM 
(SELECT *, (To_days(date_return_due)-TO_DAYS(NOW())) as dayDiff FROM mytable 
WHERE owner_id='1' 
HAVING dayDiff < 100 
ORDER BY date_created DESC) AS newtable 
GROUP BY (CASE WHEN source_id IS NULL THEN id ELSE source_id END) 
ORDER BY (CASE WHEN source_id IS NULL THEN 1 ELSE 0 END), date_created DESC"; 
+1

Astuce: utilisez 'UNION'. Oh, ajoutez la balise Oracle, si vous utilisez Oracle. –

Répondre

4

Je pense que ce qui suit fait ce que vous voulez:

SELECT *, (To_days(date_expires)-TO_DAYS(NOW())) as dayDiff, COUNT(id) AS change_count 
FROM mytable 
GROUP BY (case when source_id is null then id else source_id end) 
HAVING dayDiff < 4 
ORDER BY (case when source_id is null then 1 else 0 end), date_created DESC 

Il fait une group by conditionnelle si la Les sourcesides NULL ne seront pas groupées. Il les met ensuite en utilisant la logique en order by. Je n'ai pas compris ce que vous vouliez dire par dernière occurrence. Maintenant, je pense que je le fais:

SELECT coalesce(s.id, mytable.id) as id, 
     max(case when s.maxid is not null and s.maxid = myable.id then mytable.name 
       when s.maxid is null then NULL 
       else mytable.name 
      end) as name, 
     (To_days(date_expires)-TO_DAYS(NOW())) as dayDiff, COUNT(id) AS change_count 
FROM mytable left outer join 
    (select source_id, MAX(id) as maxid 
     from mytable 
     where source_id is not null 
     group by source_id 
    ) s 
    on mytable.id = s.maxid 
GROUP BY (case when source_id is null then id else source_id end) 
HAVING dayDiff < 4 
ORDER BY (case when source_id is null then 1 else 0 end), date_created DESC 

Ceci joint les informations de l'enregistrement le plus récent (basé sur l'ID le plus élevé).

+0

tout fonctionne bien, sauf que Group by fusionne de l'autre côté (comme décrit dans mon article: les entrées sont regroupées par première occurrence de source_id (devrait être la dernière)) – Alex

+0

@Alex. . . Je pense que j'ai la bonne logique maintenant. Je comprends les étapes.J'ai du mal à tout faire juste sans données d'échantillon. –

+0

l'a finalement fait fonctionner;) J'ai réussi à créer ma propre requête, basée sur votre première réponse (pré-éditée). Merci pour l'aide! – Alex

4

Essayez de changer group by être:

GROUP BY coalesce(source_id, id) 
0

Essayez cette

SELECT *, IFNULL (source_id, UUID()) comme unique_source DE tablename OU (conditions) GROUP BY unique_source

Questions connexes