Mysql 计算不同列值出现次数的更有效方法?
我看到了一些相关的问题,但它们似乎不是相同的情况,所以我们将不胜感激 我有当前的查询:Mysql 计算不同列值出现次数的更有效方法?,mysql,sql,Mysql,Sql,我看到了一些相关的问题,但它们似乎不是相同的情况,所以我们将不胜感激 我有当前的查询: SELECT COUNT(CASE WHEN training_enhancments.reason_id = 0 THEN 1 END) AS '0Count', COUNT(CASE WHEN training_enhancments.reason_id = 1 THEN 1 END) AS '1Count', COUNT(CASE WHEN training_enhancment
SELECT
COUNT(CASE WHEN training_enhancments.reason_id = 0 THEN 1 END) AS '0Count',
COUNT(CASE WHEN training_enhancments.reason_id = 1 THEN 1 END) AS '1Count',
COUNT(CASE WHEN training_enhancments.reason_id = 2 THEN 1 END) AS '2Count',
COUNT(CASE WHEN training_enhancments.reason_id = 3 THEN 1 END) AS '3Count',
COUNT(CASE WHEN training_enhancments.reason_id = 8 THEN 1 END) AS '4Count',
...
COUNT(CASE WHEN training_enhancments.reason_id = 40 THEN 1 END) AS '40Count',
FROM
claims claims
INNER JOIN users users ON claims.surveyor_id = users.user_id
INNER JOIN insurers insurers on claims.insurer_id = insurers.insurer_id
LEFT JOIN training_enhancments training_enhancments on claims.claim_id = training_enhancments.claim_id
WHERE
claims.claim_cancelled_id <= 0 AND
claims.date_completed BETWEEN '2014-10-01 00:00:00' AND '2014-10-31 23:59:59'
GROUP BY claims.surveyor_id;
如何重写COUNT语句以提高效率/可读性?类似于for/while循环,但我不确定它们是否存在于SQL中
谢谢。尝试通过培训\u enhanctions.reason\u id进行分组,然后在应用程序代码中,您可以使用for/while循环显示40个计数
SELECT
claims.surveyor_id,
training_enhancments.reason_id,
COUNT(*)
FROM
claims claims
INNER JOIN users users ON claims.surveyor_id = users.user_id
INNER JOIN insurers insurers on claims.insurer_id = insurers.insurer_id
LEFT JOIN training_enhancments training_enhancments on claims.claim_id = training_enhancments.claim_id
WHERE
claims.claim_cancelled_id <= 0 AND
claims.date_completed BETWEEN '2014-10-01 00:00:00' AND '2014-10-31 23:59:59'
GROUP BY
claims.surveyor_id,
training_enhancments.reason_id;
如果您需要在单独的列中使用它,您将无法获得更高的效率。但是,在MySQL中,您可以使用布尔表达式,结果为1表示true,0表示false,从而使其更具可读性:
SELECT
SUM(training_enhancments.reason_id = 0) AS '0Count',
SUM(training_enhancments.reason_id = 1) AS '1Count',
...
FROM ...
如果您需要每个测量员id有一行固定列,那么您当前的解决方案非常好 如果您可以为每个测量者id设置多行,并且可以在调用脚本中处理它们,那么Jaugar Chang的解决方案将是我的选择 如果必须为每个测量员id返回一行,但可以将返回行中的字段拆分为不同的计数,则可以执行以下操作:-
SELECT surveyor_id, GROUP_CONCAT(CONCAT_WS(':', reason_id, reason_count))
(
SELECT claims.surveyor_id, training_enhancments.reason_id, COUNT(*) AS reason_count
FROM claims claims
INNER JOIN users users ON claims.surveyor_id = users.user_id
INNER JOIN insurers insurers on claims.insurer_id = insurers.insurer_id
LEFT JOIN training_enhancments training_enhancments on claims.claim_id = training_enhancments.claim_id
WHERE claims.claim_cancelled_id <= 0
AND claims.date_completed BETWEEN '2014-10-01 00:00:00' AND '2014-10-31 23:59:59'
GROUP BY claims.surveyor_id, training_enhancments.reason_id
) sub0
GROUP BY surveyor_id;
或强制测量员使用所有原因ID的值,即使该测量员未使用任何原因ID:-
SELECT surveyor_id, GROUP_CONCAT(CONCAT_WS(':', reason_id, reason_count))
(
SELECT claims.surveyor_id, reasons.reason_id, COUNT(training_enhancments.claim_id) AS reason_count
FROM claims claims
CROSS JOIN (SELECT 0 AS reason_id UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 8 UNION SELECT 40) reasons
INNER JOIN users users ON claims.surveyor_id = users.user_id
INNER JOIN insurers insurers on claims.insurer_id = insurers.insurer_id
LEFT JOIN training_enhancments training_enhancments on claims.claim_id = training_enhancments.claim_id
WHERE claims.claim_cancelled_id <= 0
AND claims.date_completed BETWEEN '2014-10-01 00:00:00' AND '2014-10-31 23:59:59'
GROUP BY claims.surveyor_id, training_enhancments.reason_id
) sub0
GROUP BY surveyor_id;
最后,我使用周围的语言PHP进行了for循环 它更具可读性吗?值得商榷。当然,这更容易扩展
$numReasons = 38;
$SQL = "SELECT CONCAT(users.user_first_name,IF((users.user_surname<>''),CONCAT(' ',users.user_surname),'')) as 'Surveyor'";
for ($i = 0; $i < $numReasons + 1; $i++) {
$SQL .= ", COUNT(CASE WHEN training_enhancments.reason_id = $i THEN 1 END) AS '" . $i . "Count' ";
}
$SQL .= "FROM
claims claims
INNER JOIN users users ON claims.surveyor_id = users.user_id
INNER JOIN insurers insurers on claims.insurer_id = insurers.insurer_id
LEFT JOIN training_enhancments training_enhancments on claims.claim_id = training_enhancments.claim_id
您是否需要为每个测量师id带回一行,或者您是否可以为每个测量师id/原因id带回一行?如果是这样的话,您可以按测量员id、原因id进行单个计数和分组。如果你需要确保你有40行,然后交叉连接一个包含你关心的40个原因的表。是的,每行需要带回1个测量员id。Surveyors+原因是一个0-X到0-X的关系,是否可以进行单个计数?不幸的是,这不起作用,因为结果需要按Surveyors id分组,并且有几百个。你的应用程序的语言是什么?如果你只想添加额外的计数,那么你可以使用范围和数组映射来生成它们$numReasons=38$SQL=选择concaturers.user_first_name,IFusers.user_姓氏,CONCAT“”,users.user_姓氏,作为“测量者”。内爆“,”,数组映射函数$n{在训练时返回COUNTCASE\u enhanctions.reason_id=$n然后以“$n.Count”;}结尾,范围0,$numReasons。索赔