Reputation: 369
I have a query that has a math calculations and aggregate functions as following:
SELECT u.username, u.id, COUNT(t.tahmin) AS tahmins_no,
SUM(t.result = 1) AS winnings,
SUM(t.result = 2) AS loses,
sum(case when t.tahmin = 1 and t.result = 1 then 1 else 0 end) * 1 as ms1,
sum(case when t.tahmin = 2 and t.result = 1 then 1 else 0 end) * 3 as ms0,
sum(case when t.tahmin = 3 and t.result = 1 then 1 else 0 end) * 1 as ms2,
sum(case when t.tahmin = 4 and t.result = 1 then 1 else 0 end) * 2 as alt,
sum(case when t.tahmin = 5 and t.result = 1 then 1 else 0 end) * 2 as ust,
sum(case when t.tahmin = 6 and t.result = 1 then 1 else 0 end) * 3 as tg_0_1,
sum(case when t.tahmin = 7 and t.result = 1 then 1 else 0 end) * 2 as tg_2_3,
sum(case when t.tahmin = 8 and t.result = 1 then 1 else 0 end) * 4 as tg_4_6,
sum(case when t.tahmin = 9 and t.result = 1 then 1 else 0 end) * 20 as tg_7,
sum(case when t.tahmin = 10 and t.result = 1 then 1 else 0 end) * 1 as kg_var,
sum(case when t.tahmin = 11 and t.result = 1 then 1 else 0 end) * 1 as kg_yok
sum(ms1 + ms0 + ms2 + alt + ust + tg_0_1 + tg_2_3 + tg_4_6 + tg_7 + kg_var + kg_yok) as total
FROM users u
LEFT JOIN tahminler t ON u.id = t.user_id
LEFT JOIN matches_of_comments mc ON t.match_id = mc.match_id
WHERE MONTH(STR_TO_DATE(mc.match_date, '%d.%m.%Y')) = 01 AND
YEAR(STR_TO_DATE(mc.match_date, '%d.%m.%Y')) = 2014 AND flag=1
GROUP BY u.id
HAVING tahmins_no > 0
ORDER BY total DESC
The query is working very well and I get the expected results the only problem is when I add the following line to the query :
sum(ms1 + ms0 + ms2 + alt + ust + tg_0_1 + tg_2_3 + tg_4_6 + tg_7 + kg_var + kg_yok) as total
I want to order my columns by total
I want to know is that line is correct or not? is the syntax of it correct or not?
Upvotes: 0
Views: 87
Reputation: 424973
Your special sum is not actually a sum but a simple addition, which should be made using a wrapper query.
The sums of your query can be simplified by using the fact that in mysql true is 1 and false is 0 (as you are already doing for winnings
and loses
).
You also have a defect in your group by
clause: You must list all non-aggregate columns (ie username
and id
) otherwise you will get non-standard behaviour (ie the wrong result). Note how this too can also be expressed more simply.
Try this:
SELECT *, ms1 + ms0 + ms2 + alt + ust + tg_0_1 + tg_2_3 + tg_4_6 + tg_7 + kg_var + kg_yok as total FROM (
SELECT
u.username,
u.id,
COUNT(t.tahmin) AS tahmins_no,
SUM(t.result = 1) AS winnings,
SUM(t.result = 2) AS loses,
sum(t.tahmin = 1 and t.result = 1) * 1 as ms1,
sum(t.tahmin = 2 and t.result = 1 then 1 else 0 end) * 3 as ms0,
sum(t.tahmin = 3 and t.result = 1) * 1 as ms2,
sum(t.tahmin = 4 and t.result = 1) * 2 as alt,
sum(t.tahmin = 5 and t.result = 1) * 2 as ust,
sum(t.tahmin = 6 and t.result = 1) * 3 as tg_0_1,
sum(t.tahmin = 7 and t.result = 1) * 2 as tg_2_3,
sum(t.tahmin = 8 and t.result = 1) * 4 as tg_4_6,
sum(t.tahmin = 9 and t.result = 1) * 20 as tg_7,
sum(t.tahmin = 10 and t.result = 1) * 1 as kg_var,
sum(t.tahmin = 11 and t.result = 1) * 1 as kg_yok
FROM users u
LEFT JOIN tahminler t ON u.id = t.user_id
LEFT JOIN matches_of_comments mc ON t.match_id = mc.match_id
WHERE MONTH(STR_TO_DATE(mc.match_date, '%d.%m.%Y')) = 01
AND YEAR(STR_TO_DATE(mc.match_date, '%d.%m.%Y')) = 2014
AND flag=1
GROUP BY 1, 2
HAVING tahmins_no > 0) x
ORDER BY total DESC
Upvotes: 0
Reputation: 60462
You're trying to get a SUM of SUMs (noz needed in that case) and you want to reuse an alias, both are not allowed in Standard SQL (without Derived Tables).
If it's only for sorting you simply need to
ORDER BY ms1 + ms0 + ms2 + alt + ust + tg_0_1 + tg_2_3 + tg_4_6 + tg_7 + kg_var + kg_yok DESC
If you want to display the TOTAL in your SELECT list you need to repeat the calculation:
sum(case when t.tahmin = 1 and t.result = 1 then 1 else 0 end) * 1 +
sum(case when t.tahmin = 2 and t.result = 1 then 1 else 0 end) * 3 +
....
sum(case when t.tahmin = 11 and t.result = 1 then 1 else 0 end) * 1 as TOTAL
or better use a Derived Table:
SELECT username, id, tahmins_no,
winnings,
loses,
ms1,
ms0,
...
kg_yok,
ms1 + ms0 + ms2 + alt + ust + tg_0_1 + tg_2_3 + tg_4_6 + tg_7 + kg_var + kg_yok as TOTAL
FROM
(
your existing query (without ORDER BY)
) as dt
ORDER BY TOTAL DESC
Upvotes: 1