2010-11-27 18 views
1

新規の質問あります。下記の持つMySQLのデータベース/テーブルの構造:複数テーブルのMySQL問題

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()) 

私はこれは私のSQLクエリでユーザーID 1

のトランザクションの各タイプの最後のエントリを取得したいと思います:

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 

結果は次のとおりです。

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 

私もなしでGROUP BY TT.TypeIdを試してみた

...

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

私は解決策が難しいことではないと確信しているが、私は今把握することはできません。のようなものを取得したいとLD成功。

ありがとうございます!

答えて

2

これはそうすべきだと思います。トランザクションタイプを増やすと問題にはなりません。しかし、私は非常にbcをテストしていません。テストするのに便利なテーブルの "同形"(おそらく厳密には正確な用語ではない)のセットを正確には持っていません。あなたが解決しても私に知らせてください、私は興味があります。

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

こんにちは、お返事ありがとうございます。私もそれを試しました。しかし、 'tbTransaction'のエントリが正常な順序でないとうまく動作しません。つまり、2つの預金口座が引き落とされます。また、さらに 'TransactionType'が追加されるとどうなりますか?その「限界2」は働かないでしょう。 – Cybrix

+0

あなたはそれぞれのタイプの最後の2つが必要ですか?あなたのサンプル回答が反映されているものではありません - それは最後の2つの合計か、各タイプの最後のいずれかです –

+0

okあなたの編集を参照してください –

1

どのようにこの

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 

のようなもの、すべてのユーザーとトランザクション・タイプのリストを返します選択するには、最初のサブ、及びあたりの最後の取引日について。

この情報を使用して、取引テーブルに戻って残高を取得することができます。

+0

それは働いています!しかし、サブ選択なしでそれを行う方法はありますか?私が間違っていると教えてください。しかし、tbTransactionが成長するにつれてサーバがそのクエリを実行するのに問題がありますか? – Cybrix

+0

私はあなたが賢明なLIMITステートメントを可能にするトランザクションの種類を事前に決められた数だけ持っていなければ、あなたがsubselectなしでiwを実行できると思いません。インデックス作成が正しい場合は、大きな問題ではありません。 –

+0

ありがとうございました! – Cybrix

0

私は誤解しない限り、これは何をしたい、あなたは、あなたの質問にそれを持っていないされている場合は、私は ユーザーID 1

のトランザクションの各タイプの最後の2つのエントリ を取得したいと思い質問。

あなたは、各TransactionTypeの最後の2つのエントリたい:

-Depositeを:あなたは$ 200と$ 20

-WithdrawためTransactionを持っている:あなたは、正確であるかを$ 100と$ 10

ためTransactionを持っていますあなたはやろうとしていますか?

+0

はい、申し訳ありません。私はそれを編集しました:私はUserId 1のためのトランザクションの各タイプの最後のエントリを取得したいと思います – Cybrix

関連する問題