我有查询破坏了我网站的某个区域。尝试加载以下SQL语句时,该站点永远旋转!我是sql语句的新手,这个特定的语句是由另一个开发人员创建的。有没有办法优化以下声明?或者将其分解为较小的语句,以便更快地运行?我很茫然!我感谢任何帮助。
SELECT
`wp_quiz_users`.`Id`,
`wp_quiz_users`.`SessionId`,
`wp_quiz_users`.`Score`,
`wp_quiz_users`.`Date`,
`wp_quiz_users`.`Referrer`,
`wp_quiz_users`.`ContactData`,
(SELECT
SUM(`wp_quiz_users_answers`.`AnswerValue`)
FROM
`wp_quiz_users_answers`
JOIN
`wp_quiz_questions`
ON `wp_quiz_users_answers`.`QuestionId` = `wp_quiz_questions`.`id`
WHERE
`wp_quiz_users_answers`.`UserId` = `wp_quiz_users`.`Id`
AND `wp_quiz_questions`.`Category` = 1) AS `SectionOne`,
(SELECT
SUM(`wp_quiz_users_answers`.`AnswerValue`)
FROM
`wp_quiz_users_answers`
JOIN
`wp_quiz_questions`
ON `wp_quiz_users_answers`.`QuestionId` = `wp_quiz_questions`.`id`
WHERE
`wp_quiz_users_answers`.`UserId` = `wp_quiz_users`.`Id`
AND `wp_quiz_questions`.`Category` = 2) AS `SectionTwo`,
(SELECT
SUM(`wp_quiz_users_answers`.`AnswerValue`)
FROM
`wp_quiz_users_answers`
JOIN
`wp_quiz_questions`
ON `wp_quiz_users_answers`.`QuestionId` = `wp_quiz_questions`.`id`
WHERE
`wp_quiz_users_answers`.`UserId` = `wp_quiz_users`.`Id`
AND `wp_quiz_questions`.`Category` = 3) AS `SectionThree`,
(SELECT
SUM(`wp_quiz_users_answers`.`AnswerValue`)
FROM
`wp_quiz_users_answers`
JOIN
`wp_quiz_questions`
ON `wp_quiz_users_answers`.`QuestionId` = `wp_quiz_questions`.`id`
WHERE
`wp_quiz_users_answers`.`UserId` = `wp_quiz_users`.`Id`
AND `wp_quiz_questions`.`Category` = 4) AS `SectionFour`,
(SELECT
SUM(`wp_quiz_users_answers`.`AnswerValue`)
FROM
`wp_quiz_users_answers`
JOIN
`wp_quiz_questions`
ON `wp_quiz_users_answers`.`QuestionId` = `wp_quiz_questions`.`id`
WHERE
`wp_quiz_users_answers`.`UserId` = `wp_quiz_users`.`Id`
AND `wp_quiz_questions`.`Category` = 5) AS `SectionFive`
FROM
`wp_quiz_users`
答案 0 :(得分:5)
这个答案与Gordon相似,只不过它在单独的子查询中执行总和的聚合。这使得外部查询不需要聚合,因此从wp_quiz_users
表中选择任何我们想要的列应该没有任何问题。
SELECT
t1.Id,
t1.SessionId,
t1.Score,
t1.Date,
t1.Referrer,
t1.ContactData,
COALESCE(t2.SectionOne, 0) AS SectionOne,
COALESCE(t2.SectionTwo, 0) AS SectionTwo,
COALESCE(t2.SectionThree, 0) AS SectionThree,
COALESCE(t2.SectionFour, 0) AS SectionFour,
COALESCE(t2.SectionFive 0) AS SectionFive
FROM wp_quiz_users t1
LEFT JOIN
(
SELECT
t1.UserId,
SUM(CASE WHEN t2.Category = 1 THEN t1.AnswerValue ELSE 0 END) AS SectionOne,
SUM(CASE WHEN t2.Category = 2 THEN t1.AnswerValue ELSE 0 END) AS SectionTwo,
SUM(CASE WHEN t2.Category = 3 THEN t1.AnswerValue ELSE 0 END) AS SectionThree,
SUM(CASE WHEN t2.Category = 4 THEN t1.AnswerValue ELSE 0 END) AS SectionFour,
SUM(CASE WHEN t2.Category = 5 THEN t1.AnswerValue ELSE 0 END) AS SectionFive
FROM wp_quiz_users_answers t1
INNER JOIN wp_quiz_questions t2
ON t1.QuestionId = t2.id
GROUP BY t1.UserId
) t2
ON t1.Id = t2.UserId;
答案 1 :(得分:1)
我认为你只想要条件聚合:
SELECT qu.*,
SUM(CASE WHEN qq.Category = 1 THEN qa.AnswerValue END) as SectionOne,
SUM(CASE WHEN qq.Category = 2 THEN qa.AnswerValue END) as SectionTwo,
SUM(CASE WHEN qq.Category = 3 THEN qa.AnswerValue END) as SectionThree,
SUM(CASE WHEN qq.Category = 4 THEN qa.AnswerValue END) as SectionFour,
SUM(CASE WHEN qq.Category = 5 THEN qa.AnswerValue END) as SectionFive
FROM wp_quiz_users qu LEFT JOIN
wp_quiz_users_answers qa
ON qa.UserId = q.id LEFT JOIN
wp_quiz_questions qq
ON qa.QuestionId = qq.id
GROUP BY qu.UserId;
答案 2 :(得分:1)
这与Gordon Linoff的类似,但我想在某些时候添加一个关于语法的注释。 SQL的标准行为是所有不涉及聚合函数的列[例如sum()
]应列在group by
子句中。
SELECT
wp_quiz_users.Id
, wp_quiz_users.SessionId
, wp_quiz_users.Score
, wp_quiz_users.Date
, wp_quiz_users.Referrer
, wp_quiz_users.ContactData
, SUM(CASE WHEN qq.Category = 1 THEN qa.AnswerValue END) AS sectionone
, SUM(CASE WHEN qq.Category = 2 THEN qa.AnswerValue END) AS sectiontwo
, SUM(CASE WHEN qq.Category = 3 THEN qa.AnswerValue END) AS sectionthree
, SUM(CASE WHEN qq.Category = 4 THEN qa.AnswerValue END) AS sectionfour
, SUM(CASE WHEN qq.Category = 5 THEN qa.AnswerValue END) AS sectionfive
FROM wp_quiz_users qu
LEFT JOIN wp_quiz_users_answers qa ON qa.UserId = q.id
LEFT JOIN wp_quiz_questions qq ON qa.QuestionId = qq.id
GROUP BY
wp_quiz_users.Id
, wp_quiz_users.SessionId
, wp_quiz_users.Score
, wp_quiz_users.Date
, wp_quiz_users.Referrer
, wp_quiz_users.ContactData
;
即。最好列出select子句中所需的所有列,以及group by子句中列出的所有“非聚合”列。
如果你看到使用这样的查询:
select * from sometable group by name
然后该查询依赖于可以打开或关闭的非标准MySQL扩展。如果关闭该扩展名,则依赖于扩展名的查询将开始失败。因此,谨慎的编码人员可以通过简单地列出group by子句中的所有非聚合列来避免这个潜在的问题。见:https://dev.mysql.com/doc/refman/5.7/en/group-by-modifiers.html
关于原始查询,它在select子句中包含许多“相关子查询”,并且正如您所发现的那样,性能很差。请注意这些
select name
, (select sum(value) from tablex
where tablex.id = table1.id -- the "correlation" of tablex to table1 is here
)
from table1
然而,偶尔它们可能是一个不错的选择,所以尽管我们大多数时候都要避免使用它们,但我们不能说完全不使用它们。
答案 3 :(得分:0)
我会从
开始 FROM (
SELECT ua.`UserId`,
q.Category,
SUM(ua.`AnswerValue`)
FROM `wp_quiz_users_answers` AS ua
JOIN `wp_quiz_questions` AS q
ON ua.`QuestionId` = q.`id`
GROUP BY ua.`UserId`, q.Category
) AS x
JOIN wp_quiz_users AS u
ON u.Id = x.UserId
并围绕它积累。
(但是,既然我看到了其他答案,我会很懒,而不是完成这个想法。)
嗯...我想知道我的方法 - 或其他方法 - 是否会因为等待太晚而导致SUMs
膨胀GROUP BY
?