0

我目前使用子查询进行这项工作,但随着数据库的增长,这将变得非常低效。我想知道是否有一种更有效的方法可以在没有子查询的情况下完成我需要做的事情?

我需要让我的最终输出看起来像这样:

Question, Answer, Responses, Charts included in Response Count
Did this work?, N/A, 26, 30
Did this work?, Yes, 4, 30

这是我当前的查询:

SELECT
  bq_text,
  ba_a,
  bq_id,
  COUNT(ba_a)   AS ba_aC,
  (SELECT COUNT(*) FROM board_done_sheet WHERE sd_b_id = bs.bs_id AND sd_sub = 1) AS sd_chartnumC
FROM board_done_sheet AS sh
  LEFT JOIN board_done bd
    ON (bd.bd_id = sh.sd_bd_id)
  LEFT JOIN boardsubs bs
    ON (bd.bd_b_id = bs.bs_id)
  LEFT JOIN b_q_answers ba
    ON (sh.sd_s_id = ba.ba_s_id)
  LEFT JOIN bsquestions bq
    ON (bq.bq_id = ba.ba_q_id)
  LEFT JOIN multiples m
    ON (ba.ba_m_id = m.m_id)
  LEFT JOIN users u
    ON (u.us_id = bd.bd_d_id)
  LEFT JOIN profiles p
    ON (p.p_u_id = bd.bd_d_id)
  LEFT JOIN users rev
    ON (rev.us_id = bd.bd_rev)
WHERE sd_sub = '1' AND bq_text <> 'Date' AND bq_id = 380
GROUP BY bs_id, bq_text, ba_a

这很好用,问题是它必须使用随着时间的推移效率会降低的子查询。

我只是想知道如果没有它,是否有更好更有效的方法来完成求和字段。

4

1 回答 1

1

大概您关心的子查询是您的子查询 toplevel SELECT

这很容易重构,因此不会重复。

只需将其加入表的其余部分即可。你会想要这样的东西:

SELECT
 bq_text, ...
 COUNT(ba_a)   AS ba_aC,
 countup.countup AS sd_chartnumC
FROM board_done_sheet AS sh
LEFT JOIN board_done bd
           ON (bd.bd_id = sh.sd_bd_id)
...
LEFT JOIN users rev
          ON (rev.us_id = bd.bd_rev)
JOIN (
          SELECT COUNT(*) AS countup , sd_b_id
            FROM board_done_sheet 
           WHERE sd_sub = 1
        GROUP BY sd_b_id
     ) AS countup ON countup.sd_b_id = bs.bs_id
WHERE sd_sub = '1' 
  AND bq_text <> 'Date' 
  AND bq_id = 380
GROUP BY bs_id, bq_text, ba_a

子查询生成计数和 ID的countup汇总表,然后将其连接到其他表。

如果您的索引结构不正确,随着表的增长,这种复杂性的 JOIN 级联可能会因为其他原因而变得低效。

于 2013-09-11T21:49:56.550 回答