2009-09-28 8 views
0

J'ai une table Transaction (transId, sn, customerId, date) qui répertorie les transactions entre les clients. Certains articles ont le numéro de série (sn) et voyagent d'un client à l'autre. Pour certains clients (12345678), j'ai besoin de savoir qui était le dernier propriétaire précédent des articles du client.Comment obtenir le propriétaire précédent dans la table sql?

Voilà ma question:

SELECT c.*, 
      p.transId, 
      p.customerId 
    FROM Transaction c 
LEFT JOIN Transaction p ON c.sn = p.sn 
    WHERE p.transId = (SELECT MAX(t.transId) 
         FROM Transaction t 
         WHERE t.transId < c.transId 
          AND t.sn = c.sn) 
    AND c.customerId = 12345678 
ORDER BY p.transId; 

Cette requête fonctionne bien, sauf si l'article n'a pas de propriétaire précédent. Devrait retourner des valeurs nulles pour p.transId et p.customerId mais insead il retourne 0 lignes. La base de données est Accédez à.

MISE À JOUR: Je dois avoir DEUX propriétaire actuel et propriétaire précédent résultat (dans une rangée). Et, il devrait fonctionner pour les propriétaires intermédiaires (comme un journal, si le client n'est pas le propriétaire actuel, mais était un propriétaire avant).

MISE À JOUR: Pour certains clients (qui serait passé en paramètre, dans notre cas customerId = 12345678), je dois voir la liste de tous les éléments qu'il ait jamais possédé et le dernier propriétaire précédent des éléments (de quel client il a eu l'article).

Quelques autres explications:

  • TRANSID est une clé primaire et autonumber (identité) - propriétaire précédent aura TRANSID plus petit que le propriétaire récent
  • customerId dans la transaction est l'acheteur (nouveau propriétaire après cette transaction
  • La date ne contient pas d'heure; seule date (ne doit pas être utilisé dans les comparaisons ou commande depuis un certain article peut changer deux propriétaires en un jour)

Voici un petit exemple qui va rendre les choses plus claires (date non représentée):

 
     transaction table 
     ----------------------- 
     |transId|sn|customerId| 
     |  1| 1| 12345678| 
     |  2| 2| 87654321| 
     |  3| 2| 12345678| 
     |  4| 2| 11223344| 
     |  5| 2| 12345678| 
     ----------------------- 

     for customerId=12345678 result should be 

     result 
     -------------------------------------------------- 
     |transId|sn|customerId|prevTransId|prevCustomerId| 
     |  1| 1| 12345678|  NULL|   NULL| 
     |  3| 2| 12345678|   2|  87654321| 
     |  5| 2| 12345678|   4|  11223344| 
     -------------------------------------------------- 
+0

Vous avez soit obtenu mal formulé devoirs ou vous n'avez pas relayée la question avec suffisamment de précision. Est-ce «pour tout article (sn) que le clientID 12345678 a possédé, trouvez-moi le propriétaire actuel (customerID) qui possède l'article - qui ne peut plus être clientID 12345678 - et toute autre personne qui a également possédé la pièce? Ce serait compatible avec les «propriétaires intermédiaires». Ou est-ce que 'trouvez-moi le propriétaire actuel (pas nécessairement le numéro client 12345678) et le propriétaire qui * a vendu * la pièce au numéro client 12345678'? C'est une mauvaise question, et ne couvre pas les propriétaires intermédiaires. –

+0

... Ou ... eh bien, il y a d'autres interprétations possibles. Autre problème: la table de transactions enregistre-t-elle qui a vendu l'article ou qui l'a acheté (et, en effet, ne serait-il pas plus normal si enregistré à la fois qui l'a vendu et qui l'a acheté)? En outre, quelle est la granularité de la colonne de date - enregistre-t-elle l'année/mois/jour ou inclut-elle le temps?Est-ce qu'un seul article peut être vendu plusieurs fois à une date unique (probablement pas si cela inclut le temps, peut-être si cela inclut seulement l'année/mois/jour)? Avons-nous le droit de supposer que le transID augmente de façon monotone avec le temps? –

+0

Si vous avez besoin du customerID de quelqu'un qui a déjà possédé un objet que le clientID 12345678 a possédé, ce n'est pas trop difficile, même si vous voulez connaître le SN de l'article que l'autre client possédait. –

Répondre

0

état de déplacement de p.transId = ... de la clause WHERE dans une condition de jointure (et vous n'avez pas besoin c.sn = p.sn dans tous les cas):

normal SQL:

SELECT c.*, 
      p.transId, 
      p.customerId 
    FROM Transaction c 
LEFT JOIN Transaction p 
     ON p.transId = (SELECT MAX(t.transId) 
         FROM Transaction t 
         WHERE t.transId < c.transId 
          AND t.sn = c.sn) 
    WHERE c.customerId = 12345678 
ORDER BY p.transId; 

MS Access SQL:

SELECT  c.*, 
      p.transId, 
      p.customerId 
FROM  Transaction c 
LEFT JOIN ((SELECT t.transId, MAX(z.transId) AS PrevTransId 
      FROM Transaction t 
      LEFT JOIN Transaction z on t.sn = z.sn 
      WHERE z.transId < t.transId 
      GROUP BY t.transId) x 
LEFT JOIN Transaction p ON p.TransId = x.PrevTransId 
      ) ON x.TransId = c.TransId 
WHERE  c.customerId = 12345678 
ORDER BY p.transId; 
+0

J'ai déjà essayé (avant et maintenant), mais Access reports: "Erreur de syntaxe dans l'expression de requête" p.transId = (SELECT MAX (t.transId) ... '. –

+0

@BB: ajouté MS -Accès version aussi bien - brrrr, moche – van

+0

Cela fonctionne! Merci beaucoup van! –

Questions connexes