2010-09-16 7 views
1

Je suis en train de transformer cette requête en vue:requête pour le plus récent enregistrement dans une table, une requête de magasin comme vue

SELECT t.* 
FROM user t 
JOIN (SELECT t.UserId, 
       MAX(t.creationDate) 'max_date' 
     FROM user t 
    GROUP BY t.UserId) x ON x.UserId = t.UserId 
         AND x.max_date = t.creationDate 

Mais vues n'acceptent pas les sous-requêtes.

Ce que cela fait est de rechercher l'enregistrement le plus récent et le plus récent d'un utilisateur. J'ai eu l'idée de this other stackoverflow question

Y at-il un moyen de transformer cela en une requête avec des jointures, peut-être?

+0

Nous avons besoin de détails sur ce que vous avez l'intention de faire avec la sous-requête. Ne prenez pas l'habitude d'utiliser des vues pour des questions esthétiques, n'incorporez que les tables dont vous avez réellement besoin. –

+0

J'ai besoin d'obtenir le dernier enregistrement de chaque utilisateur dans la table. (Lorsqu'un utilisateur change quelque chose sur son "profil", un nouvel enregistrement est ajouté.) – skerit

Répondre

2

Créer deux vues

Create View MaxCreationDate 
As 
     SELECT t.userId, Max(t2.CreationDate) MaxCreated 
     FROM user t 
     Group By t.UserId 

Create View UserWithMaxDate 
As 
     Select t.*, m.MaxCreated From user t 
     Join MaxCreationDate m 
      On m.UserId= t.UserId 

puis il suffit d'appeler le second ...

EDIT: hey, sur la base de commentaires Quassnoi, et votre inclusion de where t.CreationDate = MaxDate en année orig sql, je Je me demande si vous voulez voir toutes les lignes pour chaque utilisateur distinct, avec la date de création maximale pour cet utilisateur dans chaque ligne, ou, voulez-vous seulement une ligne par utilisateur, la ligne qui a été créée le plus récemment?

Si ce dernier est le cas, comme @Quassnoi suggéré dans le commentaire, changer la deuxième requête de vue comme suit

Create View UserWithMaxDate 
As 
     Select t.*, m.MaxCreated From user t 
     Join MaxCreationDate m 
      On m.UserId= t.UserId 
       And m.MaxCreated = t.Creationdate 
+0

Abandonner ma réponse après avoir vu la vôtre. – Rohrbs

+1

Il n'est pas recommandé de superposer des vues les unes sur les autres. Si la vue de base change, il n'y aura pas d'erreur tant que les instructions de vue enfants ne seront pas exécutées. Cela favorise également la réutilisation des vues plutôt que la conception optimale des requêtes, en fonction de ce que les requêtes de vue font ... –

+0

@OMG Poneys, je suis d'accord, mais je ne pouvais pas penser à une autre approche qui résoudrait son problème ... Pouvez-vous? –

1
CREATE INDEX ix_user_userid_creationdate_id ON user (userid, creationdate, id); 

CREATE VIEW v_duser AS 
SELECT DISTINCT userId 
FROM user; 

CREATE VIEW v_lastuser AS 
SELECT u.* 
FROM v_duser ud 
JOIN user u 
ON  u.id = 
     (
     SELECT ui.id 
     FROM user ui 
     WHERE ui.userid = ud.userid 
     ORDER BY 
       ui.userid DESC, ui.creationdate DESC, ui.id DESC 
     LIMIT 1 
     ); 

C'est rapide et traite des doublons possibles sur (userid, creationdate).