Is there a way to sum values of the row? - mysql

I have a SQL QUERY, where im using SUM:
SELECT
SUM(CASE WHEN `ID_Event1` != 0 THEN 1 ELSE 0 END) AS count1,
SUM(CASE WHEN `ID_Event2` != 0 THEN 1 ELSE 0 END) AS count2,
SUM(CASE WHEN `ID_Event3` != 0 THEN 1 ELSE 0 END) AS count3,
SUM(CASE WHEN `ID_Event4` != 0 THEN 1 ELSE 0 END) AS count4,
SUM(CASE WHEN `ID_Event5` != 0 THEN 1 ELSE 0 END) AS count5
FROM `ec_calendar` WHERE Year(`Day`)=2015 AND Month(`Day`)=6
The result is:
But i want SUM these colums. Expected result is 17 (3+4+3+3+4).
Is there any solution?

Then use +:
SELECT (SUM(CASE WHEN `ID_Event1` != 0 THEN 1 ELSE 0 END) +
SUM(CASE WHEN `ID_Event2` != 0 THEN 1 ELSE 0 END) +
SUM(CASE WHEN `ID_Event3` != 0 THEN 1 ELSE 0 END) +
SUM(CASE WHEN `ID_Event4` != 0 THEN 1 ELSE 0 END) +
SUM(CASE WHEN `ID_Event5` != 0 THEN 1 ELSE 0 END)
) as cnt
FROM `ec_calendar`
WHERE day >= '2015-06-01' and day < '2015-07-01'
Note that I changed the WHERE clause. This method is more efficient if you have index on day.
MySQL treats booleans as integers, so you can write this as:
SELECT (SUM(ID_Event1 <> 0) + SUM(ID_Event2 <> 0) +
SUM(ID_Event3 <> 0) + SUM(ID_Event4 <> 0) +
SUM(ID_Event5 <> 0)
) as cnt
FROM `ec_calendar`
WHERE day >= '2015-06-01' and day < '2015-07-01'

You can just add the calculated columns.
SELECT
SUM(CASE WHEN `ID_Event1` != 0 THEN 1 ELSE 0 END) AS count1,
SUM(CASE WHEN `ID_Event2` != 0 THEN 1 ELSE 0 END) AS count2,
SUM(CASE WHEN `ID_Event3` != 0 THEN 1 ELSE 0 END) AS count3,
SUM(CASE WHEN `ID_Event4` != 0 THEN 1 ELSE 0 END) AS count4,
SUM(CASE WHEN `ID_Event5` != 0 THEN 1 ELSE 0 END) AS count5,
SUM(CASE WHEN `ID_Event1` != 0 THEN 1 ELSE 0 END)+
SUM(CASE WHEN `ID_Event2` != 0 THEN 1 ELSE 0 END)+
SUM(CASE WHEN `ID_Event3` != 0 THEN 1 ELSE 0 END)+
SUM(CASE WHEN `ID_Event4` != 0 THEN 1 ELSE 0 END)+
SUM(CASE WHEN `ID_Event5` != 0 THEN 1 ELSE 0 END) as total
FROM `ec_calendar` WHERE Year(`Day`)=2015 AND Month(`Day`)=6

Related

how to write mysql query with join and conditional sum with 3 tables

I have 3 mysql tables which saves invoice, invoice content and payment
inv_head(invno,invtot,invgtot)
inv_body(invno,typeid,qty,rate,linetot)
payment(invno,pay_amount,pay_method)
select inv_head.invno,inv_head.invgtot,
sum(CASE WHEN payment.pay_method='CASH' THEN payment.pay_amount ELSE 0 END) AS pay_cash,
sum(CASE WHEN payment.pay_method='CHEQUE' THEN payment.pay_amount ELSE 0 END) AS pay_chq
from inv_head left JOIN payment on inv_head.invno=payment.invno
where invdate between '2019-07-21 00:00:00' and '2019-07-21 23:00:00'
and unprodid=0
GROUP by inv_head.invno
returns below which is correct
invno invgtot pay_cash pay_chq
20190721-173208-9 242.5 100 100
20190721-174752-9 52 20 10
select inv_head.invno,inv_head.invtot,inv_head.invgtot,
sum(CASE WHEN inv_body.typeid=1 THEN inv_body.line_tot ELSE 0 END) AS stdsaletot,
sum(CASE WHEN inv_body.typeid=2 THEN inv_body.line_tot ELSE 0 END) AS rettot,
sum(CASE WHEN inv_body.typeid=3 THEN inv_body.line_tot ELSE 0 END) AS dmgtot,
sum(CASE WHEN inv_body.typeid=4 THEN (inv_body.qty * inv_body.rate)ELSE 0 END) AS fitot
from inv_head,inv_body
where invdate between '2019-07-21 00:00:00' and '2019-07-21 23:00:00'
and unprodid=0 and inv_head.invno=inv_body.invno
GROUP by inv_head.invno
returns below which is correct
invno invtot invgtot stdsaletot rettot dmgtot fitot
20190721-173208-9 242.5 242.5 242.5 0 0 0
20190721-174752-9 52 52 291 -168 -71 0
but when i combine above 2 queries,
select inv_head.invno,inv_head.invtot,inv_head.invgtot,
sum(CASE WHEN payment.pay_method='CASH' THEN payment.pay_amount ELSE 0 END) AS pay_cash,
sum(CASE WHEN payment.pay_method='CHEQUE' THEN payment.pay_amount ELSE 0 END) AS pay_chq,
sum(CASE WHEN inv_body.typeid=1 THEN inv_body.line_tot ELSE 0 END) AS stdsaletot,
sum(CASE WHEN inv_body.typeid=2 THEN inv_body.line_tot ELSE 0 END) AS rettot,
sum(CASE WHEN inv_body.typeid=3 THEN inv_body.line_tot ELSE 0 END) AS dmgtot,
sum(CASE WHEN inv_body.typeid=4 THEN (inv_body.qty * inv_body.rate)ELSE 0 END) AS fitot
from inv_body,inv_head left JOIN payment on inv_head.invno=payment.invno
where invdate between '2019-07-21 00:00:00' and '2019-07-21 23:00:00'
and unprodid=0 and inv_head.invno=inv_body.invno
GROUP by inv_head.invno
returns below result which is erroneous
invno invtot invgtot pay_cash pay_chq stdsaletot rettot dmgtot fitot
20190721-173208-9 242.5 242.5 100 100 727.5 0 0 0
20190721-174752-9 52 52 80 40 873 -504 -213 0
Your join works properly on payment and inv_head but it is not working on inv_body because you did not provided how to join inv_body with other tables
Try this hope will help you
SELECT inv_head.invno,inv_head.invtot,inv_head.invgtot,
SUM(CASE WHEN payment.pay_method='CASH' THEN payment.pay_amount ELSE 0 END) AS pay_cash,
SUM(CASE WHEN payment.pay_method='CHEQUE' THEN payment.pay_amount ELSE 0 END) AS pay_chq,
SUM(CASE WHEN inv_body.typeid=1 THEN inv_body.line_tot ELSE 0 END) AS stdsaletot,
SUM(CASE WHEN inv_body.typeid=2 THEN inv_body.line_tot ELSE 0 END) AS rettot,
SUM(CASE WHEN inv_body.typeid=3 THEN inv_body.line_tot ELSE 0 END) AS dmgtot,
SUM(CASE WHEN inv_body.typeid=4 THEN (inv_body.qty * inv_body.rate)ELSE 0 END) AS fitot
FROM payment RIGHT JOIN inv_head ON inv_head.invno=payment.invno
WHERE invdate BETWEEN '2019-07-21 00:00:00' AND '2019-07-21 23:00:00'
AND unprodid=0 LEFT JOIN inv_body ON inv_head.invno=inv_body.invno
GROUP BY inv_head.invno

How to convert this MySQL query to Eloquent?

I am trying to convert a raw SQL query into eloquent and I am struggling with the join part as it gets quite complex.
I have got as far as the joins but I am looking at the documentation and struggling to work out how to convert the rest.
Here is the raw query
SELECT
SUM(CASE WHEN t2.field_2 = 1 THEN 1 ELSE 0 END) AS 'lead',
SUM(CASE WHEN t2.field_2 = 2 THEN 1 ELSE 0 END) AS 'in_review',
SUM(CASE WHEN t2.field_2 = 3 THEN 1 ELSE 0 END) AS 'pre_app_sent',
SUM(CASE WHEN t2.field_2 = 4 THEN 1 ELSE 0 END) AS 'pre_app_back',
SUM(CASE WHEN t2.field_2 = 5 THEN 1 ELSE 0 END) AS 'pre_app_ok',
SUM(CASE WHEN t2.field_2 = 6 THEN 1 ELSE 0 END) AS 'awaiting_kyc',
SUM(CASE WHEN t2.field_2 = 7 THEN 1 ELSE 0 END) AS 'kyc_complete',
SUM(CASE WHEN t2.field_2 = 8 THEN 1 ELSE 0 END) AS 'awaiting_full_app_data',
SUM(CASE WHEN t2.field_2 = 9 THEN 1 ELSE 0 END) AS 'full_app_sent',
SUM(CASE WHEN t2.field_2 = 10 THEN 1 ELSE 0 END) AS 'merchant_live'
FROM leads l
JOIN (SELECT
ae.id,
ae.model_id,
ae.fields,
TRIM(BOTH '"' FROM SUBSTRING_INDEX(SUBSTRING_INDEX(ae.fields,';', 1), ':', -1)) AS field_1,
TRIM(BOTH '"' FROM SUBSTRING_INDEX(SUBSTRING_INDEX(ae.fields,';', 2), ':', -1)) AS field_2,
ae.created_at
FROM action_events ae) t2
ON l.id = t2.model_id
WHERE t2.created_at >= '2019-01-01 00:00:00'
AND t2.created_at <= '2019-01-31 23:59:59'
And here is as far as I got with converting it to eloquent
$query->select(
DB::raw('SUM(CASE WHEN t2.field_2 = 1 THEN 1 ELSE 0 END) AS "lead"'),
DB::raw('SUM(CASE WHEN t2.field_2 = 2 THEN 1 ELSE 0 END) AS "in_review"'),
DB::raw('SUM(CASE WHEN t2.field_2 = 3 THEN 1 ELSE 0 END) AS "pre_app_sent"'),
DB::raw('SUM(CASE WHEN t2.field_2 = 4 THEN 1 ELSE 0 END) AS "pre_app_back"'),
DB::raw('SUM(CASE WHEN t2.field_2 = 5 THEN 1 ELSE 0 END) AS "pre_app_ok"'),
DB::raw('SUM(CASE WHEN t2.field_2 = 6 THEN 1 ELSE 0 END) AS "awaiting_kyc"'),
DB::raw('SUM(CASE WHEN t2.field_2 = 7 THEN 1 ELSE 0 END) AS "kyc_complete"'),
DB::raw('SUM(CASE WHEN t2.field_2 = 8 THEN 1 ELSE 0 END) AS "awaiting_full_app_data"'),
DB::raw('SUM(CASE WHEN t2.field_2 = 9 THEN 1 ELSE 0 END) AS "full_app_sent"'),
DB::raw('SUM(CASE WHEN t2.field_2 = 10 THEN 1 ELSE 0 END) AS "merchant_live"'));

How could I check the value of an aggregation function inside the same query?

This MySQL query gives me this error 'Unknown column 'winnings' in 'field list'
SELECT
o.user_id,
sum(case when o.result = 1 or o.result=2 or o.result = 0 then 1 else 0 end) as tahmins_no,
sum(case when o.result = 1 then 1 else 0 end) as winnings,
sum(case when o.result = 2 then 1 else 0 end) as loses,
sum(case when winnings = 10 then 0.5 else 0 end) as counter
FROM `odds_tahminler` o
I know that winnings is the value of the sum() aggregation function, But is there any way to check the winnings value within the query?
You can't use an aggregated column inside the select. However you can use a subquery to obtain the counter value after all the aggregated columns have been computed.
How is the counter value calculated? I assumed that the counter should be (winnings - 10) / 2 if there's at least 10 winnings and 0 otherwise. In that case you can obtain it with this query
SELECT O.*,
GREATEST( (O.winnings - 10) / 2, 0) as counter
FROM
(
SELECT u.username,
o.user_id,
sum(case when o.result = 1 or o.result=2 or o.result = 0 then 1 else 0 end) as tahmins_no,
sum(case when o.result = 1 then 1 else 0 end) as winnings,
sum(case when o.result = 2 then 1 else 0 end) as loses
FROM `odds_tahminler` o
) as O
you can try:
SELECT
o.user_id,
sum(case when o.result = 1 or o.result=2 or o.result = 0 then 1 else 0 end) as tahmins_no,
sum(case when o.result = 1 then 1 else 0 end) as winnings,
sum(case when o.result = 2 then 1 else 0 end) as loses,
sum(case when winnings = 10 then 0.5 else 0 end) as counter
FROM `odds_tahminler` o
GROUP BY o.user_id
HAVING counter>2

i cant able to sort (Ascending/Descending) this part of MySql query?

i want to sort these elements either ascending / descending.
Part of query:
sum(CASE WHEN a.question_id=39 AND u.answer_id =215 THEN 1 ELSE 0 END) as optcount1,
sum(CASE WHEN a.question_id=39 AND u.answer_id =216 THEN 1 ELSE 0 END) as optcount2,
sum(CASE WHEN a.question_id=39 AND u.answer_id =217 THEN 1 ELSE 0 END) as optcount3,
sum(CASE WHEN a.question_id=39 AND u.answer_id =218 THEN 1 ELSE 0 END) as optcount4,
Full query:
SELECT 39 AS ques_id,215 as optid1,216 as optid2,217 as optid3,218 as optid4,
'Easy to start the business' as optans1,
'Lower tax rate than a corporation' as optans2,
'Liability is shared' as optans3,
'Owner has total control and say over business' as optans4,
sum(CASE WHEN a.question_id=39 AND u.answer_id =215 THEN 1 ELSE 0 END) as optcount1,
sum(CASE WHEN a.question_id=39 AND u.answer_id =216 THEN 1 ELSE 0 END) as optcount2,
sum(CASE WHEN a.question_id=39 AND u.answer_id =217 THEN 1 ELSE 0 END) as optcount3,
sum(CASE WHEN a.question_id=39 AND u.answer_id =218 THEN 1 ELSE 0 END) as optcount4,
'217' as answer, 4 as count FROM `user_training_answers_statistics` as u,
answers as a WHERE a.question_id='39' AND u.answer_id=a.answer_id
Anyone please give me the solution for this..
Wrap it in another query then do the sorting:
select * from
(SELECT 39 AS ques_id,215 as optid1,216 as optid2,217 as optid3,
218 as optid4, 'Easy to start the business' as optans1,
'Lower tax rate than a corporation' as optans2,
'Liability is shared' as optans3,
'Owner has total control and say over business' as optans4,
sum(CASE WHEN a.question_id=39 AND u.answer_id =215 THEN 1 ELSE 0 END)
as optcount1,
sum(CASE WHEN a.question_id=39 AND u.answer_id =216 THEN 1 ELSE 0 END)
as optcount2,
sum(CASE WHEN a.question_id=39 AND u.answer_id =217 THEN 1 ELSE 0 END)
as optcount3,
sum(CASE WHEN a.question_id=39 AND u.answer_id =218 THEN 1 ELSE 0 END)
as optcount4, '217' as answer, 4 as count
FROM user_training_answers_statistics as u,
answers as a
WHERE a.question_id='39' AND u.answer_id=a.answer_id) as tmpTable
ORDER BY optcount1, optcount2, optcount3, optcount4 ASC;

mySQL query comparing rows and columns

I have a database of user answers from a quiz which contains 8 questions. Q1 - Q8 all are their own columns, I'd like to compare all the rows and get a number back for everyone who answered the same for at least 5 questions.
so here, rows 5 and 6 would count as 2. Basically I'm trying to get a number for everyone who answered at least 5 questions the same. Is this possible with a mySQL query?
EDIT:
Here the user enters D B D A B C D B, matching with 2 similarly answered quizzes. The query here would return a count of 2.
If we test using just your single line of D B D A B C D B we can use the following example:
SELECT * FROM `answers` WHERE ((CASE WHEN q1 = 'D' THEN 1 ELSE 0 END) +
(CASE WHEN q2 = 'B' THEN 1 ELSE 0 END) +
(CASE WHEN q3 = 'D' THEN 1 ELSE 0 END) +
(CASE WHEN q4 = 'A' THEN 1 ELSE 0 END) +
(CASE WHEN q5 = 'B' THEN 1 ELSE 0 END) +
(CASE WHEN q6 = 'C' THEN 1 ELSE 0 END) +
(CASE WHEN q7 = 'D' THEN 1 ELSE 0 END) +
(CASE WHEN q8 = 'B' THEN 1 ELSE 0 END)) >= 5;
However, if we then want to go a step further and test each answer against the other answers in the table we can use the following statement:
SELECT *, (SELECT COUNT(answer_sub.idanswers) FROM `answers` answer_sub
WHERE ((CASE WHEN answer_sub.q1 = a.q1 THEN 1 ELSE 0 END) +
(CASE WHEN answer_sub.q2 = a.q2 THEN 1 ELSE 0 END) +
(CASE WHEN answer_sub.q3 = a.q3 THEN 1 ELSE 0 END) +
(CASE WHEN answer_sub.q4 = a.q4 THEN 1 ELSE 0 END) +
(CASE WHEN answer_sub.q5 = a.q5 THEN 1 ELSE 0 END) +
(CASE WHEN answer_sub.q6 = a.q6 THEN 1 ELSE 0 END) +
(CASE WHEN answer_sub.q7 = a.q7 THEN 1 ELSE 0 END) +
(CASE WHEN answer_sub.q8 = a.q8 THEN 1 ELSE 0 END)) >= 5
AND answer_sub.idanswers <> a.idanswers) as matching
FROM `answers` a
WHERE (SELECT COUNT(answer_sub.idanswers) FROM `answers` answer_sub
WHERE ((CASE WHEN answer_sub.q1 = a.q1 THEN 1 ELSE 0 END) +
(CASE WHEN answer_sub.q2 = a.q2 THEN 1 ELSE 0 END) +
(CASE WHEN answer_sub.q3 = a.q3 THEN 1 ELSE 0 END) +
(CASE WHEN answer_sub.q4 = a.q4 THEN 1 ELSE 0 END) +
(CASE WHEN answer_sub.q5 = a.q5 THEN 1 ELSE 0 END) +
(CASE WHEN answer_sub.q6 = a.q6 THEN 1 ELSE 0 END) +
(CASE WHEN answer_sub.q7 = a.q7 THEN 1 ELSE 0 END) +
(CASE WHEN answer_sub.q8 = a.q8 THEN 1 ELSE 0 END)) >= 5
AND answer_sub.idanswers <> a.idanswers) > 0
Because FALSE is 0 and TRUE is 1 in MySQL:
SELECT COUNT(*)
FROM quiz
WHERE ( (q1=#q1) + (q2=#q2) + (q3=#q3) + (q4=#q4)
+ (q5=#q5) + (q6=#q6) + (q7=#q7) + (q8=#q8)
) >= 5