2011-09-13 3 views
2

J'écris une application pour android et j'ai une base de données SQLite3 assez simple (voir image), mais j'ai beaucoup de problèmes avec une requête spécifique.Aide à la requête SQLite

Voici (une partie de) la base de données. Remarque: il existe une relation un-à-plusieurs ici. Un joueur peut avoir beaucoup d'événements mais seulement 1 joueur pour chaque événement.

Table model

Je veux avoir une liste de tous les joueurs, mais je dois commander cette liste de tous les acteurs selon qu'ils ont un événement qui a son Diagnosed attribut défini sur false ou non (Tous les joueurs avec un événement "Undiagnosed" vont en haut, tous les autres joueurs viennent après). S'ils ont plus d'un événement "Non diagnostiqué" que le plus récent est utilisé.

C'est la partie la plus délicate de la requête. Après cela, les joueurs avec les événements "Undiagnosed" doivent être classés par leur attribut "Magnitude" (int), et les autres joueurs (tout joueur qui n'a aucun évènement "non diagnostiqué") doivent être triés par leur nom de famille. .

Voici un exemple de la liste que j'ai besoin:

  • Joueur < --1 événement Undiagnosed (100 magnitude)
  • du joueur < --2 événements non diagnostiqués (Le plus récent un 75 magnitude)
  • Joueur < --1 événement Undiagnosed (50 grandeur)
  • Joueur < - Non (Nom des événements non diagnostiqués: Johnny Appleseed)
  • Joueur < - Aucun événement non diagnostiqué (Nom: Jim Zebra)

La seule façon que je peux penser à faire est d'utiliser 2 requêtes distinctes (une pour « joueurs » et non diagnostiqué un autre pour tout le monde) mais je n » Je pense que c'est la meilleure façon de le faire.

Merci d'avance!

Modifier

Ok, donc ici est la requête qui est la plupart du temps de travail maintenant.

select player.PlayerID, player.fname, player.lname, stats.diagcount, topmag.magnitude 
from player left outer join (
select playerid, MIN(diagnosed) as diagcount 
from events group by playerid 
)as stats on player.playerid = stats.playerid 
left outer join (
select playerid,max(magnitude) as magnitude 
from events group by playerid 
)as topmag on player.playerid=topmag.playerid 
order by CASE WHEN stats.diagcount Is NULL Then 1 Else 0 End,stats.diagcount,topmag.magnitude,lname; 

Le seul problème est maintenant que les joueurs en bas de la liste (joueurs sans aucun événement diagnostiqués) sont triés par leur ampleur de l'événement le plus récent et non par nom.

+1

'« La seule façon que je peux penser à faire est d'utiliser 2 requêtes distinctes (un pour les joueurs «non diagnostiqués» et un autre pour tous les autres) mais je ne pense pas que ce soit la meilleure façon de faire cela. »' Ne supposez pas qu'une requête composée de vues en ligne et de syndicats est faussée dès le départ ou fonctionnerait mal - l'optimiseur peut parfois avoir un temps plus facile avec de telles requêtes, et ils sont certainement plus lisibles et maintenables parce que les sous-ensembles discrets sont plus clairement représentés. – Tim

Répondre

1

quelque chose comme:

select player.fname, player.lname, stats.diagcount, topmag.highest 
from player left outer join (
    select playerid, count(time) as diagcount 
    from events group by playerid 
)as stats on player.playerid = stats.playerid 
left outer join (
    select playerid,max(magnitude) as highest 
    from events group by playerid 
)as topmag on player.playerid=topmag.playerid 
order by stats.diagcount,topmag.highest,lname 

dunno ce qui est possible dans SqlLite mais je pense que quelque chose comme ça pourrait fonctionner, si vous obtenez des erreurs les poster et je verrai ce que je peux faire

Si vous voulez éliminer le tri par magnitude du joueur dont les événements sont diagnostiqués, vous pouvez alors les éliminer des sous-requêtes.

select player.fname, player.lname, stats.diagcount, topmag.highest 
from player left outer join (
    select playerid, count(time) as diagcount 
    from events 
    where diagnosed = 0 
    group by playerid 
)as stats on player.playerid = stats.playerid 
left outer join (
    select playerid,max(magnitude) as highest 
    from events 
    where diagnosed = 0 
    group by playerid 
)as topmag on player.playerid=topmag.playerid 
order by stats.diagcount,topmag.highest,lname 

désolé, je aurais peut-être la chose diagnostiquée dans le mauvais sens (comme dans peut-être le diagnostic devrait être = 1)

+0

Hey @Gordatron. Merci pour l'aide! Nous avons peaufiné votre requête (ce qui est très bien et nous a mis sur la bonne voie!) Et ça marche très bien. Je posterai le code mis à jour dans la question. Il y a juste un problème ... Un joueur qui a été diagnostiqué est également trié par leur magnitude (s'ils avaient un événement) et non par leur nom de famille. N'importe quelle façon de faire 'si diagnostiqué == 1 alors commande par lname'? Je noterai toujours ceci comme réponse, merci! – javajavajavajavajava

+0

mis à jour la réponse avec une option possible .. il ne retournera aucune information sur les événements diagnostiqués – gordatron