连接表以从唯一行获取最新行

时间:2012-12-07 08:13:27

标签: mysql sql join greatest-n-per-group

我有两张桌子

表结构就是这样的

表A

╔══════╦════════╗
║ P_ID ║ P_NAME ║
╠══════╬════════╣
║    1 ║ name1  ║
║    2 ║ name2  ║
║    3 ║ name3  ║
║    4 ║ name5  ║
╚══════╩════════╝

表B

╔═════╦════════╦════════╦═══════════╦═══════╗
║ ID  ║  P_ID  ║  C_ID  ║  C_PRICE  ║  TIME ║
╠═════╬════════╬════════╬═══════════╬═══════╣
║  1  ║      1 ║      3 ║        11 ║ 11111 ║
║  2  ║      2 ║      4 ║        22 ║ 22222 ║
║  3  ║      3 ║      5 ║        33 ║ 33333 ║
║  4  ║      3 ║      6 ║        44 ║ 44444 ║
║  5  ║      3 ║      6 ║        55 ║ 55555 ║
║  6  ║      4 ║      7 ║        66 ║ 66666 ║
╚═════╩════════╩════════╩═══════════╩═══════╝

要求是
1.加入两个表
2.按C_ID分组
3.分组中的最新行

我试图通过How do I join the most recent row in one table to another table?

修改Bill Karwin的答案
SELECT e.*, s1.*  
FROM table_a e   
INNER JOIN
table_b s1
    ON (e.p_id = s1.p_id)   
LEFT OUTER JOIN table_b s2
    ON (e.p_id = s2.p_id AND s1.id < s2.id) 
WHERE s2.p_id IS NULL;

但我无法实现我的目标。根据他的回答,我会得到

╔═════╦════════╦════════╦═══════════╦═══════╦═════════╗
║ ID  ║  P_ID  ║  C_ID  ║  C_PRICE  ║  TIME ║  P_NAME ║
╠═════╬════════╬════════╬═══════════╬═══════╬═════════╣
║  1  ║      1 ║      3 ║        11 ║ 11111 ║ name1   ║
║  2  ║      2 ║      4 ║        22 ║ 22222 ║ name2   ║
║  5  ║      3 ║      6 ║        55 ║ 55555 ║ name3   ║
║  6  ║      4 ║      7 ║        66 ║ 66666 ║ name5   ║
╚═════╩════════╩════════╩═══════════╩═══════╩═════════╝

但是我想要的输出如下(dublicate P_ID是好的但是对于每个dublicate P_ID不应该有dublicate C_ID)

╔═════╦════════╦════════╦═══════════╦═══════╦═════════╗
║ ID  ║  P_ID  ║  C_ID  ║  C_PRICE  ║  TIME ║  P_NAME ║
╠═════╬════════╬════════╬═══════════╬═══════╬═════════╣
║  1  ║      1 ║      3 ║        11 ║ 11111 ║ name1   ║
║  2  ║      2 ║      4 ║        22 ║ 22222 ║ name2   ║
║  3  ║      3 ║      5 ║        33 ║ 33333 ║ name3   ║
║  5  ║      3 ║      6 ║        55 ║ 55555 ║ name3   ║
║  6  ║      4 ║      7 ║        66 ║ 66666 ║ name5   ║
╚═════╩════════╩════════╩═══════════╩═══════╩═════════╝

2 个答案:

答案 0 :(得分:1)

SELECT e.*, s1.*
FROM table_a e INNER JOIN 
(SELECT * FROM (SELECT * FROM table_b ORDER BY time DESC) temp GROUP BY c_id) s1;

最里面的ORDER BY确保对于相同的c_id,所需的行始终排在第一位,outter GROUP BY将在c_id上分组,否则未指定将返回为每个组找到的第一行。

答案 1 :(得分:0)

你必须

  1. 加入两个表
  2. 按C_ID分组
  3. 按所选字段排序的每个组desc的数字行(最后暗示订单!)
  4. 按行号过滤= 1。
  5. This可以帮助您对行进行编号。