先生,我还不清楚问题中的要求。
我将使用示例来解释我的困惑。
请看一个简单的演示:http ://sqlfiddle.com/#!2/19f52c/6
这个演示包含一个简化的(为了清楚起见)数据库结构和查询。
来自问题的查询(演示中的第一个查询)返回以下结果:
SELECT action.actionid
FROM ACTION
INNER JOIN EVENT
ON action.eventid = event.eventid
LEFT JOIN
(SELECT
COUNT(1),
action.eventid
FROM
ACTION
WHERE (action.typeid = '2')
GROUP BY action.eventid) AS act
ON act.eventid = event.eventid
WHERE -- actiondate2 BETWEEN 20130601 AND 20131031 AND
event.siteid = 1
AND action.typeid = 1
;
+ ------------- +
| actionid |
+ ------------- +
| 1 |
| 3 |
| 5 |
+ ------------- +
然而,在上面的查询中,带有别名的子查询ACT
只是......没用。
查询执行这个子查询(消耗时间和服务器资源),然后......忽略它的结果,只是把它们扔掉。
上面的查询等效于下面的查询(演示中的第二个查询)——它返回与问题中的查询相同的结果,但不使用子查询(节省时间和资源,因此性能会更好):
SELECT action.actionid
FROM
ACTION
INNER JOIN EVENT
ON action.eventid = event.eventid
WHERE -- actiondate2 BETWEEN 20130601 AND 20131031 AND
event.siteid = 1
AND action.typeid = 1
;
+ ------------- +
| actionid |
+ ------------- +
| 1 |
| 3 |
| 5 |
+ ------------- +
如果您的意图是优化问题中的查询显示- 那么请简单地使用上面显示的查询,这就是您问题的答案。
但是,查看您对预期结果的评论,似乎问题中的查询可能是错误的——它没有给出预期的结果。
好吧,但仍然不清楚查询应该给出什么?有很多可能性,我将在下面展示其中的一些。
如果您需要列出所有action.actionid
,typeid = 1
但只列出这样的记录,它存在任何具有相同eventid
和typeid = 2
...的记录,然后使用以下查询(演示中的第三个查询):
SELECT a.actionid
FROM
ACTION a
INNER JOIN EVENT e
ON a.eventid = e.eventid
WHERE -- actiondate2 BETWEEN 20130601 AND 20131031 AND
EXISTS ( SELECT 1 FROM action a1
WHERE a1.eventid = a.eventid
AND a1.typeid = 2
)
AND e.siteid = 1
AND a.typeid = 1
;
+ ------------- +
| actionid |
+ ------------- +
| 1 |
| 3 |
+ ------------- +
这个查询使用了EXISTS
操作符,而不是COUNT()
- 如果我们想要一条存在相同记录的信息,我们不需要计算所有这些信息!计数必须读取所有记录,EXISTS
如果找到满足条件的第一条记录,则停止读取表 - 因此EXISTS
通常比COUNT()
.
如果你需要用 列出所有action.actionid
,typeid = 1
并显示一些对应记录存在的信息typeid = 2
- 然后使用下面的查询(演示中的第四个查询):
SELECT
a.actionid ,
CASE WHEN EXISTS ( SELECT 1 FROM action a1
WHERE a1.eventid = a.eventid
AND a1.typeid = 2
)
THEN 'typeid=2 EXISTS'
ELSE 'typeid=2 DOESN''T EXIST'
END typeid2_exist
FROM
ACTION a
INNER JOIN EVENT e
ON a.eventid = e.eventid
WHERE -- actiondate2 BETWEEN 20130601 AND 20131031 AND
e.siteid = 1
AND a.typeid = 1
;
+ ------------- + ---------------------- +
| actionid | typeid2_exist |
+ ------------- + ---------------------- +
| 1 | typeid=2 EXISTS |
| 3 | typeid=2 EXISTS |
| 5 | typeid=2 DOESN'T EXIST |
+ ------------- + ---------------------- +
但是如果你真的需要用typeid = 2
- 来计算对应的记录,那么这个查询可以提供帮助(演示中的第五个查询):
SELECT
a.actionid ,
( SELECT count(*) FROM action a1
WHERE a1.eventid = a.eventid
AND a1.typeid = 2
) typeid2_count
FROM
ACTION a
INNER JOIN EVENT e
ON a.eventid = e.eventid
WHERE -- actiondate2 BETWEEN 20130601 AND 20131031 AND
e.siteid = 1
AND a.typeid = 1
;
+ ------------- + ------------------ +
| actionid | typeid2_count |
+ ------------- + ------------------ +
| 1 | 1 |
| 3 | 1 |
| 5 | 0 |
+ ------------- + ------------------ +
如果上面显示的查询都不符合您的要求,请显示(基于演示中的示例数据)查询应返回的结果 - 这有助于本论坛中的某人构建满足您所有要求的正确查询。
然后,当我们识别出满足所有期望的正确查询时,我们就可以开始优化它的性能了。