合并多个 select 与更新
Combine multiple select with update
我有一个拖累我的应用程序的查询。必须有一种方法可以通过将更新与选择结合起来来改进这一点。任何帮助表示赞赏。这是非常慢的查询:
Select t1.id, t2.tracker from Table1 t1, Table2 t2 where t1.id=t2.id and t2.tracker is not null
以上returns一行集我可以处理。对于返回的每一行,我检查跟踪器
第三个 table 查看是否只有 1 行存在:
select tracker from Table3 where tracker="from above query".
如果跟踪器在 Table 3 中有 1 行的计数,那么我会在 Table 1 上执行更新。
Update Table 1, set some field where id=t1.id
我该如何合并呢?列出的答案很棒,但我想问题还不够清楚。因此,我编辑了问题。
Table 1 returns 可能要更新的 ID 列表。
Table 2 returns 我需要搜索的跟踪器 Table 3.
Table 3 告诉我跟踪器是否只存在一次,所以我可以用它返回到 Table 1 和
更新一下。
通过使用 HAVING
子句和附加的 LEFT JOIN
,您可以将前两个查询合并为一个查询,只为那些在 [=15= 中有一条记录的查询返回 tracker
] 用 HAVING COUNT(t3.tracker) = 1
这样的表达式
SELECT
部分看起来像:
SELECT
t1.id,
t2.tracker
FROM
-- Your original comma-separated FROM clause (implicit inner join)
-- has been replaced with a more modern explicit INNER JOIN, which
-- works more clearly with the LEFT JOIN we need to do.
Table1 t1
INNER JOIN Table2 t2 ON t1.id = t2.id
-- left join table 3 by tracker value
LEFT JOIN Table3 t3 ON t2.tracker = t3.tracker
WHERE t2.tracker IS NOT NULL
GROUP BY
t1.id,
t2.tracker
-- limit the group to only those with 1 tracker in t3
HAVING COUNT(t3.tracker) = 1
现在,您应该 能够使用 JOIN
将其填充到 UPDATE
查询中。 MySQL 的更新连接语法如下所示:
UPDATE
Table1 t_up
-- join Table1 in its normal form against the query from above
-- MySQL won't allow an IN () subquery for update in most versions
-- so it has to be done as a join instead.
JOIN (
-- the subquery only needs to return t1.id
SELECT t1.id
FROM
Table1 t1
INNER JOIN Table2 t2 ON t1.id = t2.id
LEFT JOIN Table3 t3 ON t2.tracker = t3.tracker
-- Filter to those with non-null t2.tracker
WHERE t2.tracker IS NOT NULL
GROUP BY
-- Since only id was in SELECT, only id needs to be in GROUP BY
t1.id
HAVING COUNT(t3.tracker) = 1
) t_set ON t_up.id = t_set.id
SET t_up.some_field = 'SOME NEW VALUE'
Here is a demonstration of the concept in action...
我有一个拖累我的应用程序的查询。必须有一种方法可以通过将更新与选择结合起来来改进这一点。任何帮助表示赞赏。这是非常慢的查询:
Select t1.id, t2.tracker from Table1 t1, Table2 t2 where t1.id=t2.id and t2.tracker is not null
以上returns一行集我可以处理。对于返回的每一行,我检查跟踪器 第三个 table 查看是否只有 1 行存在:
select tracker from Table3 where tracker="from above query".
如果跟踪器在 Table 3 中有 1 行的计数,那么我会在 Table 1 上执行更新。
Update Table 1, set some field where id=t1.id
我该如何合并呢?列出的答案很棒,但我想问题还不够清楚。因此,我编辑了问题。
Table 1 returns 可能要更新的 ID 列表。 Table 2 returns 我需要搜索的跟踪器 Table 3. Table 3 告诉我跟踪器是否只存在一次,所以我可以用它返回到 Table 1 和 更新一下。
通过使用 HAVING
子句和附加的 LEFT JOIN
,您可以将前两个查询合并为一个查询,只为那些在 [=15= 中有一条记录的查询返回 tracker
] 用 HAVING COUNT(t3.tracker) = 1
SELECT
部分看起来像:
SELECT
t1.id,
t2.tracker
FROM
-- Your original comma-separated FROM clause (implicit inner join)
-- has been replaced with a more modern explicit INNER JOIN, which
-- works more clearly with the LEFT JOIN we need to do.
Table1 t1
INNER JOIN Table2 t2 ON t1.id = t2.id
-- left join table 3 by tracker value
LEFT JOIN Table3 t3 ON t2.tracker = t3.tracker
WHERE t2.tracker IS NOT NULL
GROUP BY
t1.id,
t2.tracker
-- limit the group to only those with 1 tracker in t3
HAVING COUNT(t3.tracker) = 1
现在,您应该 能够使用 JOIN
将其填充到 UPDATE
查询中。 MySQL 的更新连接语法如下所示:
UPDATE
Table1 t_up
-- join Table1 in its normal form against the query from above
-- MySQL won't allow an IN () subquery for update in most versions
-- so it has to be done as a join instead.
JOIN (
-- the subquery only needs to return t1.id
SELECT t1.id
FROM
Table1 t1
INNER JOIN Table2 t2 ON t1.id = t2.id
LEFT JOIN Table3 t3 ON t2.tracker = t3.tracker
-- Filter to those with non-null t2.tracker
WHERE t2.tracker IS NOT NULL
GROUP BY
-- Since only id was in SELECT, only id needs to be in GROUP BY
t1.id
HAVING COUNT(t3.tracker) = 1
) t_set ON t_up.id = t_set.id
SET t_up.some_field = 'SOME NEW VALUE'