2013-11-27 103 views
0

我(使用UNION ALL,因爲我有萬噸行的MySQL的選擇與UNION ALL

SELECT id, max(lastdate) AS lastdate, max(san) AS san 
FROM 
    (SELECT `san` AS id, 
      `created` AS lastdate, 
      '' AS san 
    FROM `TableA` a 
    UNION ALL 
    SELECT `san` AS id, 
      cast(null as datetime) AS lastdate, 
      `san-name` AS san 
    FROM `TableB` b 
    ) sq 
GROUP BY id 
ORDER BY san ASC 

表A

| id | san | status |  created  | 
------------------------------------------- 
| 1 | 100 | 3 | 2013-11-01 19:26:20 | 
| 2 | 200 | 8 | 2013-11-02 03:19:35 | 
| 3 | 300 | 1 | 2013-11-03 06:13:38 | 
| 4 | 100 | 2 | 2013-11-06 08:28:37 | 
| 5 | 100 | 4 | 2013-11-27 19:00:00 | 
| 6 | 200 | 1 | 2013-11-27 19:16:22 | 
| 7 | 200 | 3 | 2013-11-27 19:33:33 | 
| 8 | 300 | 5 | 2013-11-27 19:50:29 | 

表B

| san | san-name | 
------------------ 
| 100 | xxx1 | 
| 200 | xxx2 | 
| 300 | xxx3 | 

與此查詢

我得到這個結果(一切都運行完美)

| id |  lastdate  | san | 
-------------------------------------- 
| 100 | 2013-11-27 19:00:00 | xxx1 | 
| 200 | 2013-11-27 19:33:33 | xxx2 | 
| 300 | 2013-11-27 19:50:29 | xxx3 | 


,但現在我也想加入的「創造」最新的「ID」,「身份」到我的結果。


從TableA的,我想行(見< - 最新的San .....)

,它應該是這樣的:

| id | status |  lastdate  | san | 
------------------------------------------------ 
| 100 | 4 | 2013-11-27 19:00:00 | xxx1 | 
| 200 | 3 | 2013-11-27 19:33:33 | xxx2 | 
| 300 | 5 | 2013-11-27 19:50:29 | xxx3 | 

我用此代碼試用過

SELECT id, status, max(lastdate) AS lastdate, max(san) AS san 
FROM 
    (SELECT `san` AS id, 
      `created` AS lastdate, 
      '' AS san, 
      status AS status 
    FROM `TableA` a 
    UNION ALL 
    SELECT `san` AS id, 
      cast(null as datetime) AS lastdate, 
      `san-name` AS san, 
      '' AS status 
    FROM `TableB` b 
    ) sq 
GROUP BY id 
ORDER BY san ASC 

,但它給了我這個(錯誤的結果)

| id | status |  lastdate  | san | 
------------------------------------------------ 
| 100 | 3 | 2013-11-27 19:00:00 | xxx1 | 
| 200 | 8 | 2013-11-27 19:33:33 | xxx2 | 
| 300 | 1 | 2013-11-27 19:50:29 | xxx3 | 

,不正確的是這樣

| id | status |  lastdate  | san | 
------------------------------------------------ 
| 100 | 4 | 2013-11-27 19:00:00 | xxx1 | 
| 200 | 3 | 2013-11-27 19:33:33 | xxx2 | 
| 300 | 5 | 2013-11-27 19:50:29 | xxx3 | 

有人能幫助我嗎? :O)

我創建了一個sqlfiddle

問候

bernte

回答

1

我會嘗試與此查詢:

SELECT tA.san AS id, tA.status, tA.created AS lastdate, tB.`san-name` 
FROM 
    tableA tA INNER JOIN (SELECT san, MAX(created) AS max_created 
         FROM tableA 
         GROUP BY san) m 
    ON tA.san=m.san AND tA.created=m.max_created 
    INNER JOIN tableB tB 
    ON tA.san=tB.san 

請參閱小提琴here

編輯

如果您需要從tableB的返回所有的記錄,只有符合您需要使用正確的記錄JOIN(這是一個有點少見),或者我們可以交換表的順序加入並使用LEFT JOIN,類似這樣的:

SELECT tB.san AS id, tA.status, tA.created AS lastdate, tB.`san-name` 
FROM 
    tableB tB LEFT JOIN 
    (SELECT san, MAX(created) AS max_created 
    FROM tableA 
    GROUP BY san) m 
    ON tB.san=m.san 
    LEFT JOIN TableA tA 
    ON tA.san=m.san AND tA.created=m.max_created 

小提琴是here

+0

嗨..感謝您的評論!我會稍後在我的服務器上嘗試。希望你的代碼是快速的:D與我的舊代碼花了30秒..所以我不得不選擇工會所有 – bernte

+1

@bernte我希望它是正確的,並像聯合查詢一樣快:)如果它應該也更容易閱讀!如果速度太慢,我會嘗試在兩個表的san列上添加索引,並在創建的列上添加索引。 – fthiella

+0

該指數應該如何?我從來沒有這樣做過 – bernte