2

我有两张这样的桌子,

表格1 :

+-------------+--------+--------+--------+
| contract_id | price1 | price2 | price3 |
+-------------+--------+--------+--------+
|           1 |     23 |     45 |     56 |
|           1 |     22 |     21 |    453 |
|           1 |     45 |    564 |    456 |
|           4 |     22 |     21 |    453 |
|           5 |     45 |    564 |    456 |
+-------------+--------+--------+--------+

和表2,

+-------------+--------+---------+
| contract_id | owner  | address |
+-------------+--------+---------+
|           1 | Me     | Madras  |
|           1 | father | Chennai |
+-------------+--------+---------+

我想将两个表拼接在一起,结果看起来像,

+-------------+--------+--------+--------+--------+---------+
| contract_id | price1 | price2 | price3 | owner  | address |
+-------------+--------+--------+--------+--------+---------+
|           1 |     23 |     45 |     56 | Me     | Madras  |
|           1 |     22 |     21 |    453 | father | Chennai |
|           1 |     45 |    564 |    456 | NULL   | NULL    |
|           4 |     22 |     21 |    453 | NULL   | NULL    |
|           5 |     45 |    564 |    456 | NULL   | NULL    |
+-------------+--------+--------+--------+--------+---------+

目前我正在手动迭代第二个表并更新第一个表中的相应行以实现这一点。我想出的其他方法是进行外部联接并清理重复的行。有没有更好的方法来获得结果?

4

3 回答 3

2

这应该可以完美地工作。首先,我计算两个表的排名,然后使用LEFT JOIN基于排名的这两个表连接,这样输出中不会有任何重复,因为它是一对一的映射。

试试这个查询:

SELECT 
    a.contract_id, a.price1, a.price2, a.price3, b.owner, b.address
FROM 
    (SELECT 
         contract_id, price1, price2, price3, (@rank := @rank + 1) AS rank
     FROM 
         table1, (SELECT @rank := 0) tmp) a
LEFT JOIN 
    (SELECT 
         contract_id, owner, address, (@rank := @rank + 1) AS rank
     FROM 
         table2, (SELECT @rank := 0) tmp) b ON a.rank = b.rank
ORDER BY 
    a.rank ASC;

编辑更准确的查询:您需要为匹配的contract_ids创建嵌套排名:

SELECT 
    a.c_id, a.price1, a.price2, a.price3, b.owner, b.address
FROM 
    (SELECT 
         @var_rank := IF(contract_id <> @var_id_prev,1, @var_rank+1) AS vrank,
         @var_id_prev := contract_id AS c_id,
         price1, price2, price3, @rank := (@rank + 1) AS rnk
     FROM 
         table1, (SELECT @var_id_prev := 0) tmp
     ORDER BY 
         contract_id) a
LEFT JOIN 
    (SELECT 
         @var_rank := IF(contract_id <> @var_id_prev,  1, 
         @var_rank+1) AS vrank,
         @var_id_prev := contract_id AS c_id,
         owner, address, @rank := @rank + 1 AS rnk
     FROM 
         table2, (SELECT @var_id_prev := 0) tmp
     ORDER BY 
         contract_id) b ON a.c_id = b.c_id AND a.vrank = b.vrank
ORDER BY 
    a.c_id, a.vrank ASC;

SQL FIDDLE 演示在这里

但更好的方法是放在auto id两个表上并在连接条件下使用它。

通过这样做,表被规范化,它将节省在计算排名时在内存中创建临时表的额外开销。它还将通过在这些连接列上使用索引来加速查询。

于 2012-08-17T09:35:47.967 回答
1

我们必须通过它的Row_Number加入这两个表。

尝试这个:

SELECT a.contract_id, a.price1, a.price2, a.price3, b.owner, b.address
FROM (SELECT contract_id, price1, price2, price3, (@rank := @rank + 1) AS rank
      FROM t1, (SELECT @rank := 0) tmp
     )a
LEFT JOIN 
     (SELECT contract_id, owner, address, (@rank1 := @rank1 + 1) AS rank
      FROM t2, (SELECT @rank1 := 0) tmp
     )b
ON a.rank = b.rank
AND a.contract_id = b.contract_id
ORDER BY a.rank ASC;

看到这个 SQLFiddle

于 2012-08-17T09:17:11.133 回答
0

您需要显示这两个表之间的关系,而不是使查询复杂化。规范化第一张表,使用外键交叉引用相关数据。我会这样做:

在此处输入图像描述

查询如下所示:

SELECT table1.contract_id, table1.price1, table1.price2, table1.price3, table2.name, table2.address
FROM table1
LEFT JOIN table2 ON table1.owner_id = table2.id;
于 2012-08-17T09:56:34.880 回答