2013-11-27 76 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