MySQL在单个查询中访问两个表

时间:2014-03-21 09:55:10

标签: mysql sql

这是我的麻烦的简化版本。 3表,第一个(中转)将在即将到来的程序和功能中使用,第二个(产品)将保存有关产品的固定数据,第三个(userWatchList)将保存与产品相关的用户特定数据。

TABLE: transit
+---------+------+
| ranking | data |
+---------+------+
|         |      |
+---------+------+
TABLE: products
+----+------+-----------------+
| ID | data | importantnumber |
+----+------+-----------------+
|  1 | c    |              10 |
|  2 | u    |              20 |
|  3 | t    |              20 |
|  4 | u    |              40 |
+----+------+-----------------+
TABLE: userWatchList
+---------+----+
| ranking | ID |
+---------+----+
|       1 |  2 |
|       2 |  1 |
|       3 |  4 |
|       4 |  3 |
+---------+----+

我需要插入" transit"在所需排名范围内且其数据满足特定要求的行的数据和排名。

我现在想要产品的排名和数据,其importantnumber值为20。 假设允许的排名范围介于1和2之间,在所需流程结束时输出SELECT * FROM transit

+---------+------+
| ranking | data |
+---------+------+
|       1 | 'u'  |
+---------+------+

假设允许的排名范围在1到3之间,在所需流程结束时输出SELECT * FROM transit

+---------+------+
| ranking | data |
+---------+------+
|       1 | 'u'  |
|       4 | 't'  |
+---------+------+

我对可能解决方案的看法...... 为了确保排名在所需范围内,我想我可能会使用动态SQL:

SET @IDsRetrieveStmt = CONCAT("SELECT group_concat(ID SEPARATOR ',') INTO @IDsStr FROM userWatchList WHERE ranking BETWEEN ', @rankingmin,' AND ', @rankingmax,';');
PREPARE stmt FROM @IDsRetrieveStmt;
EXECUTE stmt;

现在。要为这些字段添加排名值......我该怎么办?我想一个选项就是:

SET @fetch_data_stmt = CONCAT('INSERT INTO transit (data, ranking) SELECT  data, ( **** ) FROM products WHERE ID IN ( ', @IDsStr, ') AND importantnumber=20;');
PREPARE stmt FROM @fetch_data_stmt;
EXECUTE stmt;

* * 这里有一些未知的魔法,可以从'产品'中使用相同ID的行获取排名。表。这可能是SELECT ranking FROM userWatchList WHERE ID=ID,但如您所见,ID部分可能会产生冲突。此外,对每个插入的行运行新的SELECT查询似乎有点无效。 我确信有一种更有效的方式可以做到这一点,我还没有听说过。

实现这一目标的最佳方法是什么?提前谢谢!

1 个答案:

答案 0 :(得分:2)

答案的第一个也是最重要的部分是生成所需数据的查询。您需要将两个表连接在一起,并将您的条件用作查询中的条件:

select ranking, data
from userWatchList u
join product p on p.ID = u.ID
where ranking between ? and ? 
and importantnumber = ?

当然用您的标准替换?

答案的下一部分是更多建议。除非有非常令人信服的理由这样做,否则创建一个表来保存此查询的数据输出,因为它的派生数据已经过时了它是创建的,除非你放入复杂的数据库基础设施(触发器)以保持新鲜。

相反,创建一个视图就像一个表到客户端(一个应用程序),但实际上是一个查询:

create view transit as
select ranking, data, importantnumber
from userWatchList u
join product p on p.ID = u.ID

然后使用:

select ranking, data
from transit
where ranking between ? and ? 
and importantnumber = ?