首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MySQL子查询效率

问MySQL子查询效率
EN

Stack Overflow用户
提问于 2013-04-17 00:48:22
回答 2查看 270关注 0票数 1

我有这个查询,它向'stats‘表中添加了大量的值。当查询运行时,它选择值来填充子查询中的表。我想知道这是否可以做得更有效率,或者我是否做错了什么。我对MySQL不是很熟悉,所以任何帮助都是非常好的:)

下面是查询:

代码语言:javascript
复制
UPDATE mediastats SET 
    mediastats_members = (SELECT count(*) FROM status WHERE status_media_id = :id),
    mediastats_avscore = (SELECT AVG(status_rating) FROM status WHERE status_media_id = :id),
    mediastats_done = (SELECT count(*) FROM status WHERE status_status = 'done' AND status_media_id = :id),
    mediastats_doing = (SELECT count(*) FROM status WHERE status_status = 'doing' AND status_media_id = :id),
    mediastats_redoing = (SELECT count(*) FROM status WHERE status_status = 'redoing' AND status_media_id = :id),
    mediastats_dropped = (SELECT count(*) FROM status WHERE status_status = 'dropped' AND status_media_id = :id),
    mediastats_wantto = (SELECT count(*) FROM status WHERE status_status = 'wantto' AND status_media_id = :id),
    mediastats_wont = (SELECT count(*) FROM status WHERE status_status = 'wont' AND status_media_id = :id),
    mediastats_stalled = (SELECT count(*) FROM status WHERE status_status = 'stalled' AND status_media_id = :id),
    mediastats_rating_1 = (SELECT count(*) FROM status WHERE status_rating = 1 AND status_media_id = :id),
    mediastats_rating_2 = (SELECT count(*) FROM status WHERE status_rating = 2 AND status_media_id = :id),
    mediastats_rating_3 = (SELECT count(*) FROM status WHERE status_rating = 3 AND status_media_id = :id),
    mediastats_rating_4 = (SELECT count(*) FROM status WHERE status_rating = 4 AND status_media_id = :id),
    mediastats_rating_5 = (SELECT count(*) FROM status WHERE status_rating = 5 AND status_media_id = :id),
    mediastats_rating_6 = (SELECT count(*) FROM status WHERE status_rating = 6 AND status_media_id = :id),
    mediastats_rating_7 = (SELECT count(*) FROM status WHERE status_rating = 7 AND status_media_id = :id),
    mediastats_rating_8 = (SELECT count(*) FROM status WHERE status_rating = 8 AND status_media_id = :id),
    mediastats_rating_9 = (SELECT count(*) FROM status WHERE status_rating = 9 AND status_media_id = :id),
    mediastats_rating_10 = (SELECT count(*) FROM status WHERE status_rating = 10 AND status_media_id = :id)
    WHERE mediastats_media_id = :id

:id是从PHP添加的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-04-17 01:05:16

下面是我如何在PHP中使用PDO来做这件事:

代码语言:javascript
复制
$sql = "
    SELECT
     COUNT(*) AS mediastats_members,
     AVG(status_rating) AS mediastats_avscore,
     SUM(status_status = 'done') AS mediastats_done,
     SUM(status_status = 'doing') AS mediastats_doing,
     SUM(status_status = 'redoing') AS mediastats_redoing,
     SUM(status_status = 'dropped') AS mediastats_dropped,
     SUM(status_status = 'wantto') AS mediastats_wantto,
     SUM(status_status = 'wont') AS mediastats_wont,
     SUM(status_status = 'stalled') AS mediastats_stalled,
     SUM(status_rating = 1) AS mediastats_rating_1,
     SUM(status_rating = 2) AS mediastats_rating_2,
     SUM(status_rating = 3) AS mediastats_rating_3,
     SUM(status_rating = 4) AS mediastats_rating_4,
     SUM(status_rating = 5) AS mediastats_rating_5,
     SUM(status_rating = 6) AS mediastats_rating_6,
     SUM(status_rating = 7) AS mediastats_rating_7,
     SUM(status_rating = 8) AS mediastats_rating_8,
     SUM(status_rating = 9) AS mediastats_rating_9,
     SUM(status_rating = 10) AS mediastats_rating_10
    FROM status
    WHERE status_media_id = :id";
$stmt = $pdo->prepare($sql);
$stmt->execute(array("id"=>$id));
$params = $stmt->fetch(PDO::FETCH_ASSOC);

这样,您可以在表的一次传递中计算所有聚合,而不是对每个计数使用单独的子查询。

我使用了一个计数技巧--布尔表达式的MySQL ()等于表达式为真时的COUNT()。这是因为MySQL布尔表达式总是返回0或1,并且0和1的和等于1的计数。

然后,您可以使用上述查询的结果作为UPDATE语句的参数数组:

代码语言:javascript
复制
$sql = "
    UPDATE mediastats SET 
        mediastats_members = :mediastats_members,
        mediastats_avscore = :mediastats_avscore,
        mediastats_done = :mediastats_done,
        mediastats_doing = :mediastats_doing,
        mediastats_redoing = :mediastats_redoing,
        mediastats_dropped = :mediastats_dropped,
        mediastats_wantto = :mediastats_wantto,
        mediastats_wont = :mediastats_wont,
        mediastats_stalled = :mediastats_stalled,
        mediastats_rating_1 = :mediastats_rating_1,
        mediastats_rating_2 = :mediastats_rating_2,
        mediastats_rating_3 = :mediastats_rating_3,
        mediastats_rating_4 = :mediastats_rating_4,
        mediastats_rating_5 = :mediastats_rating_5,
        mediastats_rating_6 = :mediastats_rating_6,
        mediastats_rating_7 = :mediastats_rating_7,
        mediastats_rating_8 = :mediastats_rating_8,
        mediastats_rating_9 = :mediastats_rating_9,
        mediastats_rating_10 = :mediastats_rating_10
    WHERE mediastats_media_id = :id";

$stmt = $pdo->prepare($sql);
$params["id"] = $id;
$stmt->execute($params);

从PHP5.3.4开始,PDO接受不带前导:的参数数组键。在查询中声明参数占位符时需要冒号,但不需要在提供给execute()的值数组中使用冒号。

票数 2
EN

Stack Overflow用户

发布于 2013-04-17 00:56:05

代码语言:javascript
复制
UPDATE  (
        SELECT  status_media_id,
                COUNT(*) AS cnt, AVG(status_rating) AS avg_rating,
                SUM(status_status = 'done') AS cnt_done,
                ...
        FROM    status
        WHERE   status_media_id = :id
        ) s
JOIN    mediastats ms
ON      ms.mediastats_media_id = s.status_media_id
SET     ms.mediastats_members = cnt,
        ms.mediastats_avscore = avg_rating,
        ms.mediastats_done = cnt_done,
        ...
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16042625

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档