2010-11-27 4 views
1

newb question là. Avoir base de données MySQL/structure tableaux ci-dessous:Problème MySQL avec plusieurs tables

CREATE DATABASE `dbTest` 

CREATE TABLE IF NOT EXISTS `dbTest`.`tbUser` (

    `UserId` INT UNSIGNED NOT NULL AUTO_INCREMENT , 

    `Username` VARCHAR(45) NOT NULL , 

    PRIMARY KEY (`UserId`)) 

ENGINE = InnoDB 

CREATE TABLE IF NOT EXISTS `dbTest`.`tbTransactionType` (

    `TypeId` INT UNSIGNED NOT NULL AUTO_INCREMENT , 

    `Name` VARCHAR(45) NOT NULL , 

    PRIMARY KEY (`TypeId`)) 

ENGINE = InnoDB 

CREATE TABLE IF NOT EXISTS `dbTest`.`tbTransaction` (

    `TransactionId` INT NOT NULL AUTO_INCREMENT , 

    `UserId` INT UNSIGNED NOT NULL , 

    `TransactionType` INT UNSIGNED NOT NULL , 

    `Balance` DOUBLE NOT NULL , 

    `Date` DATETIME NOT NULL , 

    PRIMARY KEY (`TransactionId`) , 

    INDEX `FK_tbTransaction_tbUser_UserId` (`UserId` ASC) , 

    INDEX `FK_tbTransaction_tbTransactionType_TransactionId` (`TransactionType` ASC) , 

    CONSTRAINT `FK_tbTransaction_tbUser_UserId` 

    FOREIGN KEY (`UserId`) 

    REFERENCES `dbTest`.`tbUser` (`UserId`) 

    ON DELETE NO ACTION 

    ON UPDATE NO ACTION, 

    CONSTRAINT `FK_tbTransaction_tbTransactionType_TransactionId` 

    FOREIGN KEY (`TransactionType`) 

    REFERENCES `dbTest`.`tbTransactionType` (`TypeId`) 

    ON DELETE NO ACTION 

    ON UPDATE NO ACTION) 

ENGINE = InnoDB 

INSERT INTO `dbTest`.`tbUser` (`UserId`, `Username`) VALUES ('1', 'User1'); 
INSERT INTO `dbTest`.`tbTransactionType` (`TypeId`, `Name`) VALUES ('1', 'Deposite'); 
INSERT INTO `dbTest`.`tbTransactionType` (`TypeId`, `Name`) VALUES ('2', 'Withdraw'); 

INSERT INTO `dbTest`.`tbTransaction` (`TransactionId`, `UserId`, `TransactionType`, `Balance`, `Date`) VALUES (NULL, '1', '1', '200', NOW()) 
INSERT INTO `dbTest`.`tbTransaction` (`TransactionId`, `UserId`, `TransactionType`, `Balance`, `Date`) VALUES (NULL, '1', '2', '100', NOW()) 
INSERT INTO `dbTest`.`tbTransaction` (`TransactionId`, `UserId`, `TransactionType`, `Balance`, `Date`) VALUES (NULL, '1', '1', '20', NOW()) 
INSERT INTO `dbTest`.`tbTransaction` (`TransactionId`, `UserId`, `TransactionType`, `Balance`, `Date`) VALUES (NULL, '1', '2', '10', NOW()) 

Je voudrais obtenir l'dernière entrée de chaque type de transaction pour le UserId 1

Ceci est ma requête SQL:

SELECT U.Username, TT.Name, T.Balance, T.Date 
FROM tbUser U 
INNER JOIN tbTransaction T ON T.UserId = U.UserId 
INNER JOIN tbTransactionType TT ON TT.TypeId = T.TransactionType 
WHERE U.UserId = 1 

Et le résultat est:

Username Name  Balance Date 
User1 Deposite 200  2010-11-26 23:11:40 
User1 Deposite 20  2010-11-26 23:14:56 
User1 Withdraw 100  2010-11-26 23:11:58 
User1 Withdraw 10  2010-11-26 23:14:56 

Quand je wou ld comme pour obtenir quelque chose comme:

Username Name  Balance Date 
User1  Deposite 20  2010-11-26 23:14:56 
User1  Withdraw 10  2010-11-26 23:14:56 

Je suis sûr que la solution est pas difficile, mais je ne peux pas comprendre en ce moment ...

J'ai aussi essayé un GROUP BY TT.TypeId sans Succès.

Merci!

Répondre

2

Je pense que cela devrait le faire, et ce ne sera pas un problème si vous ajoutez plus de types de transactions. Cependant, je n'ai pas tout à fait testé bc. Je n'ai pas exactement un ensemble de tables "isomorphes" (probablement pas exactement le bon terme) pour les tester. S'il vous plaît laissez-moi savoir même si vous êtes résolu, je suis curieux.

SELECT U.Username, TT.Name, T.Balance, T.Date 
FROM tbUser U 
INNER JOIN tbTransaction T ON T.UserId = U.UserId 
INNER JOIN tbTransactionType TT ON TT.TypeId = T.TransactionType 
WHERE U.UserId = 1 AND 
     T2.Date = (SELECT MAX(T2.date) 
       FROM tbTransaction T2 WHERE 
       T2.UserID = U.UserId, T2.TransactionType = T.TransactionType) 
+0

Salut, merci pour votre réponse. J'ai essayé celui-là aussi. Mais cela ne fonctionnera pas si les entrées dans 'tbTransaction' ne sont pas dans le bon ordre. Je veux dire, deux dépositions puis un retrait sont faits. Aussi, que se passe-t-il si plus de 'TransactionType' sont ajoutés? Ce 'Limit 2' ne fonctionnera pas. – Cybrix

+0

donc vous voulez les deux derniers de chaque type? ce n'est pas ce que votre exemple de réponse reflète - c'est soit le total des deux derniers, ou le dernier de chaque type –

+0

ok je vois votre édition –

1

Que diriez-vous quelque chose comme ça

SELECT lt.Username, 
     lt.Name, 
     T.Balance, 
     T.Date 
FROM (
      SELECT u.UserID, 
        u.UserName, 
        T.TransactionType, 
        TT.Name, 
        MAX(t.Date) LastDate 
      FROM tbUser U INNER JOIN 
        tbTransaction T ON T.UserId = U.UserId INNER JOIN 
        tbTransactionType TT ON TT.TypeId = T.TransactionType 
      GROUP BY u.UserID, 
         u.UserName, 
         T.TransactionType, 
         TT.Name 
     ) lt INNER JOIN 
     tbTransaction T ON T.UserId = lt.UserId 
         AND t.TransactionType = lt.TransactionType 
         AND t.Date = lt.LastDate 
WHERE lt.UserId = 1 

Le premier sous select retournera une liste de tous les utilisateurs et les types de transactions, et la dernière date de la transaction par.

Vous pouvez ensuite REJOINDRE la table Transactions en utilisant ces informations pour récupérer les soldes.

+0

Cela fonctionne! Mais y a-t-il un moyen de le faire sans sous-sélection? Dites-moi si je me trompe, mais le serveur aura-t-il de la difficulté à exécuter cette requête à mesure que tbTransaction se développera? – Cybrix

+0

Je ne pense pas que vous serez en mesure de faire iw sans la sous-sélection, sauf si vous avez un nombre prédéfini de types de transactions pour permettre une instruction LIMIT intelligente. Si votre indexation est correcte, cela ne devrait pas poser de gros problèmes. –

+0

Okay. Je vous remercie! – Cybrix

0

Je voudrais obtenir les deux dernière entrée de chaque type de transaction pour le UserId 1

Si c'est ce que vous voulez, alors vous avez cela dans votre question, à moins que je mal compris la question.

Vous voulez deux dernières entrées pour chaque TransactionType:

-Deposite: vous avez le Transaction pour 200 $ et 20

$ -Retirer: vous avez la Transaction pour 100 $ et 10 $

ce sont exactement vous essayez de faire?

+0

Oui désolé à ce sujet. Je l'ai édité: je voudrais obtenir la dernière entrée de chaque type de transaction pour le UserId 1 – Cybrix

Questions connexes