请看一下这两个问题:
一:
INSERT INTO QandA (id, body, type, related, author_id, date_time)
SELECT NULL, :body, 0, NULL, :id, unix_timestamp
FROM (select count(*) as num_month,
count(date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 day))) as num_day,
count(date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 90 minute))) as num_90min
from QANDA
where author_id = :id and
type = 0 and
date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 50 day))
) a
WHERE num_month < 50 and num_day < 6 and num_90min < 1;
两个
INSERT INTO QandA (id, body, type, related, author_id, date_time)
SELECT NULL, :body, 0, NULL, :id, unix_timestamp
FROM dual
WHERE user_id = :id
AND NOT EXISTS (
SELECT count(*) AS num_month
count(date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 day))) as num_day,
count(date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 90 minute))) as num_90min
FROM QandA
WHERE author_id = :id and
type = 0 and
date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 50 day))
HAVING num_90min > 50
OR num_day > 6
OR num_month > 1
)
如您所见,两者都是相同的,只有第一个使用外部查询,第二个使用 having
子句。哪种方法更好?或者有没有比他们更好的第三种方法?
答案 0 :(得分:0)
第一个是标准SQL,所以你应该理解它。
第二个是MySQL中having
子句的扩展。通常,having
子句仅用于聚合查询 - 您会在查询中的某处看到聚合函数。在MySQL(以及其他几个数据库)中,having
允许使用列别名,而WHERE
子句则不允许。
让我们再添加一个重要的考虑因素。通常,MySQL 实现子查询。这意味着子查询会产生额外的开销来写出数据并将其读回。大多数其他数据库都有更好的优化器,并且没有实现FROM
子句中的所有/大多数子查询。
因此,为了提高效率,MySQL允许您在非聚合查询中使用HAVING
子句。在这种情况下,它的作用就像一个WHERE
子句,除了你可以引用列别名。
结论:第一个更好,因为它是更标准的SQL。第二个更好,因为它应该运行得更快。一切都取决于你所说的“更好”。