2012-01-20 16 views
2

私は2つのテーブルを持っています:コースと許可。私はSELECTを実行しようとしていますが、特定の学生の既存のすべてのコースの最新の許可値を特定のアカウントで表示しています。MySQLは最新の日付のレコードを選択します

SELECT COURSES.NAME, PERMISSIONS.VALUE, PERMISSIONS.TS 
FROM COURSES LEFT JOIN PERMISSIONS 
ON PERMISSIONS.C_ID = COURSES.C_ID AND PERMISSIONS.S_ID = '12345' 
WHERE COURSES.A_ID = 'ABCDE' 

私が得る結果は、私は、最新のタイムスタンプ(TS)とのレコードのみを表示することです必要なもの

NAME   | VALUE | TS 
----------------------------------------------- 
Mathematics | 1  | 2012-01-19 19:13:21 
Mathematics | 0  | 2012-01-19 19:13:15 
Mathematics | 0  | 2012-01-19 19:20:19 
Mathematics | 0  | 2012-01-19 19:20:27 
Mathematics | 0  | 2012-01-19 19:21:29 
Biology  |   | 

あるので、これを示しています。今

、私はこれを行います:

NAME   | VALUE | TS 
----------------------------------------------- 
Mathematics | 0  | 2012-01-19 19:21:29 
Biology  |   | 

私はTIのORDER BYと一緒にコース名にGROUP BYを試してみましたそれは正しいレコードを受け取っていませんでした。

誰でもお手伝いできますか?

答えて

0
SELECT COURSES.NAME, PL.VALUE, PL.TS 
FROM COURSES 
LEFT JOIN 
    (SELECT 
     PERMISSIONS.C_ID, PERMISSIONS.VALUE, PERMISSIONS.TS 
    FROM PERMISSIONS 
    JOIN 
     (SELECT P.C_ID, MAX(P.TS) AS LATEST 
     FROM PERMISSIONS P 
     WHERE P.S_ID = '12345' 
     GROUP BY P.C_ID) PG 
    ON PERMISSIONS.TS = PG.LATEST) PL 
    ON PL.C_ID = COURSES.C_ID 
WHERE COURSES.A_ID = 'ABCDE' 

をデータのサイズについて、PERMISSIONSテーブルのインデックス(C_ID、TS)を追加すると、最新の日付を早く見つけることができます:

ALTER TABLE `PERMISSIONS` ADD INDEX (`C_ID`,`TS`); 
+0

素晴らしい作業!正しい道で私を得ました。第2サブ-SELECTに「WHERE PERMISSIONS.S_ID = '12345'」を追加しました。 – greener

2

HAVINGを使用する必要があります。だから、この

SELECT COURSES.NAME, PERMISSIONS.VALUE, PERMISSIONS.TS 
FROM COURSES LEFT JOIN PERMISSIONS 
ON PERMISSIONS.C_ID = COURSES.C_ID AND PERMISSIONS.S_ID = '12345' 
WHERE COURSES.A_ID = 'ABCDE' 
GROUP BY COURSES.A_ID 
HAVING PERMISSIONS.TS = MAX(PERMISSIONS.TS) 

(それはテーブル構造と容易になるだろう)

別の可能性のようなもので行くべきそれを反対の方法を考えることです。自身の権限テーブルに参加して、

SELECT COURSES.NAME, PA.VALUE, PA.TS 
    FROM COURSES LEFT JOIN PERMISSIONS PA 
    ON PA.C_ID = COURSES.C_ID AND PA.S_ID = '12345' 
    WHERE COURSES.A_ID = 'ABCDE' 
     AND (PA.C_ID == NULL || NOT EXISTS (
      SELECT * 
      FROM PERMISSIONS PB 
      WHERE PA.C_ID = PB.C_ID AND PB.S_ID = '12345' AND PB.TS > PA.TS)) 
+0

私は両方のオプションを試しましたが、結果が期待どおりではありません。例えば、HAVINGオプションはレコードを返しません。 – greener

+0

HAVINGにエラーがある可能性があります。もう一つは、あなたはどんな問題を抱えていますか?複数の数学の行または生物学(実際には、はい、私はnullの場合がありません) – Luis

0

別の方法として高いタイムスタンプを持っていない権限を見つける - 許可テーブルの最大タイムスタンプを計算する副選択を持つ:

によって
SELECT courses.name, x.value, x.timestamp 
FROM courses 
LEFT JOIN (SELECT p1.c_id, p1.s_id, p1.value, p1.timestamp 
    FROM permissions p1 
    LEFT JOIN permissions p2 ON p1.c_id = p2.c_id AND p1.s_id = p2.s_id AND p1.timestamp < p2.timestamp 
    WHERE p2.timestamp IS NULL) x ON courses.c_id = x.c_id AND x.s_id = '12345' 
WHERE courses.a_id = 'ABCDE' 
関連する問題