UPDATE a field with sum of other fields with conditions MYSQL - mysql

My Table structure is as follows
counter1|counter1_status|counter2|counter2_status|counter3|counter3_status|valid_counter
-----------------------------------------------------------------------------------------
5 0 6 1 3 1 XXXX
I want a single update query to update valid_counter as 6 + 3 = 9
As counter1_status = 0, counter1 should not be added
Tried following query, but it gives error.
UPDATE counter_table
SET valid_contact =
SUM((CASE WHEN counter1_status=1 THEN counter1 ELSE 0 END)
+ (CASE WHEN counter2_status=1 THEN counter2 ELSE 0 END)
+ (CASE WHEN counter3_status=1 THEN counter3 ELSE 0 END))
I can get the sum by using SELECT query without any error, but Update query failed.

if you want to conditionally store sum of (counter1,counter2,counter3) in the valid_contace field, you may use:
UPDATE counter_table
SET valid_contact =
(CASE WHEN counter1_status=1 THEN counter1 ELSE 0 END)
+ (CASE WHEN counter2_status=1 THEN counter2 ELSE 0 END)
+ (CASE WHEN counter3_status=1 THEN counter3 ELSE 0 END)
where id=5

UPDATE counter_table AS c1 JOIN
(SELECT id, SUM((CASE WHEN counter1_status=1 THEN counter1 ELSE 0 END)
+ (CASE WHEN counter2_status=1 THEN counter2 ELSE 0 END)
+ (CASE WHEN counter3_status=1 THEN counter3 ELSE 0 END)) AS m
FROM counter_table) AS c2
USING (id)
SET c1.`valid_counter` = c2.m;
Sample fiddle

Finally got the solution for error :
SUM should be removed from the query.
It should be SUM(a,b,c)
or a+b+c.
UPDATE counter_table
SET valid_contact =
((CASE WHEN counter1_status=1 THEN counter1 ELSE 0 END)
+ (CASE WHEN counter2_status=1 THEN counter2 ELSE 0 END)
+ (CASE WHEN counter3_status=1 THEN counter3 ELSE 0 END))

Related

Multiple Count with Multiple column

I am new in sql. I want to count something like:
Select count(*) from table where col1= x and col2=x and Col3=x.
I need to count the same value in all different column.
Any help will be appreciated.
You can use conditional aggregation :
Select sum(case when col1='x' then 1 else 0 end) as count_col1,
sum(case when col2='x' then 1 else 0 end) as count_col2,
sum(case when col3='x' then 1 else 0 end) as count_col3
from tab;
If you want to have sum of these count values, consider the above query as an inner and use the following :
Select q.*,
q.count_col1 + q.count_col2 + q.count_col3 whole_sum
from
(
Select sum(case when col1='x' then 1 else 0 end) as count_col1,
sum(case when col2='x' then 1 else 0 end) as count_col2,
sum(case when col3='x' then 1 else 0 end) as count_col3
from tab
) q
Rextester Demo

Is there a way to include the sum of all cases?

Given SQL: Is there a way to bring in the total of the result set?
SELECT
SUM(CASE
WHEN status = 3 THEN 1
ELSE 0
END) AS Open,
SUM(CASE
WHEN status = 4 THEN 1
ELSE 0
END) AS Close
FROM
Table1
WHERE
id = 2;
Result:
Open,Close
5,5
Desired Result:
Open,Close,Total
5,5,10
just add another case statement
SELECT
SUM(CASE
WHEN status = 3 THEN 1
ELSE 0
END) AS Open,
SUM(CASE
WHEN status = 4 THEN 1
ELSE 0
END) AS Close
SUM(CASE
WHEN status IN (3, 4) THEN 1
ELSE 0
END) AS Total
FROM
Table1
WHERE
id = 2;
You can use a CTE:
WITH sumCase AS (
SELECT
SUM(CASE
WHEN status = 3 THEN 1
ELSE 0
END) AS Open,
SUM(CASE
WHEN status = 4 THEN 1
ELSE 0
END) AS Close
FROM
Table1
WHERE
id = 2;)
SELECT Open,Close, Open + Close AS Total FROM Table1;
http://www.mysqltutorial.org/mysql-cte/
using sub-query
select open,close,open+close as total from
(
SELECT
SUM(CASE WHEN status = 3 THEN 1
ELSE 0
END ) AS Open,
SUM(CASE WHEN status = 4 THEN 1
ELSE 0
END) AS Close
FROM
Table1
WHERE id = 2 ) as T

SSRS calculate % of desired colums in column group in matrix

SELECT PatchPhase.PhaseName, MAX(PatchPhase.Sequence) AS seq,
PatchState.Application, PatchState.Objectname, PatchState.Jobname,
PatchState.Streamname, COUNT(*) AS Total,
PatchState.Jobdescription,
PatchState.Status, PatchState.Timestamp
FROM PatchState
INNER JOIN PatchPhase ON PatchState.Phase = PatchPhase.PhaseTech
WHERE (PatchPhase.PhaseName IN (#Phase))
AND (PatchState.Application IN (#Application)) AND (PatchState.Timestamp >= #StartDate)
AND (PatchState.Timestamp <= #EndDate)
GROUP BY PatchPhase.PhaseName, PatchState.Application, PatchState.Objectname,
PatchState.Jobname, PatchState.Streamname, PatchState.Jobdescription, PatchState.Status,
PatchState.Timestamp
ORDER BY PatchState.Application
I am working on matrix and I have column group of status which contains 3 columns (planned, running,completed). I want to sum planned+completed and divide by total column.
Total column is outside the column group.
I do find some answers but I did not get how should I use in my code
can someone please help?
Try using this to aggregate, and then use a table instead of a matrix. You will not need a column group now. As I cannot run the sql I can't promise it is perfect but perhaps you could have a little play with it if not. It should offer a guide if nothing else.
SELECT
PatchPhase.PhaseName,
MAX(PatchPhase.Sequence) AS seq,
PatchState.Application,
PatchState.Objectname,
PatchState.Jobname,
PatchState.Streamname,
PatchState.Jobdescription,
SUM(case when PatchState.Status = 'Planned' then 1 else 0 end) as 'Planned',
SUM(case when PatchState.Status = 'Running' then 1 else 0 end) as 'Running',
SUM(case when PatchState.Status = 'Completed' then 1 else 0 end) as 'Completed',
(SUM(case when PatchState.Status = 'Planned' then 1 else 0 end) + SUM(case when PatchState.Status = 'Running' then 1 else 0 end)) /
(SUM(case when PatchState.Status = 'Planned' then 1 else 0 end) + SUM(case when PatchState.Status = 'Running' then 1 else 0 end) + SUM(case when PatchState.Status = 'Completed' then 1 else 0 end)) as totalPercentage
PatchState.Timestamp
FROM
PatchState
INNER JOIN PatchPhase
ON PatchState.Phase = PatchPhase.PhaseTech
WHERE
(PatchPhase.PhaseName IN (#Phase))
AND (PatchState.Application IN (#Application))
AND (PatchState.Timestamp >= #StartDate)
AND (PatchState.Timestamp <= #EndDate)
GROUP BY
PatchPhase.PhaseName,
PatchState.Application,
PatchState.Objectname,
PatchState.Jobname,
PatchState.Streamname,
PatchState.Jobdescription,
PatchState.Status,
PatchState.Timestamp
ORDER BY
PatchState.Application
You can get a value displayed in a text box from expression =Reportitems!Textbox133.Value
instead of textbox133 in the above expression you have to give the textbox name of the textbox from which you want the value. In your case the total column

Update certain columns based on date. Best way to approach this issue

I have a table I need to update. In this table there is a column for each month. If someone's start date is 2/13/2015 I need to update the February column with some data from a calculation.
So if Start_Date is 2/17/2015 then the value for the February column called FTEFeb needs to be populated. If the Start_Date is 3/09/2015 then the FTEMar column needs to be updated etc...
I was thinking a CASE statment would work but the SET column would be different based on the value in Start Date.
I've looked online for anything similar and nothing came up.
Thanks in advance!
You can use a case statement.
For your query, instead of preforming a CASE on the month, just write a case to update each column, and if the column is not the month you want you can set it to 0, or whatever your business rule is. Try this:
UPDATE myTable
SET
FTEJan = (CASE WHEN MONTH(startDate) = 1 THEN 1 ELSE 0 END),
FTEFeb = (CASE WHEN MONTH(startDate) = 2 THEN 1 ELSE 0 END),
FTEMar = (CASE WHEN MONTH(startDate) = 3 THEN 1 ELSE 0 END),
FTEApr = (CASE WHEN MONTH(startDate) = 4 THEN 1 ELSE 0 END),
FTEMay = (CASE WHEN MONTH(startDate) = 5 THEN 1 ELSE 0 END),
FTEJun = (CASE WHEN MONTH(startDate) = 6 THEN 1 ELSE 0 END),
FTEJul = (CASE WHEN MONTH(startDate) = 7 THEN 1 ELSE 0 END),
FTEAug = (CASE WHEN MONTH(startDate) = 8 THEN 1 ELSE 0 END),
FTESep = (CASE WHEN MONTH(startDate) = 9 THEN 1 ELSE 0 END),
FTEOct = (CASE WHEN MONTH(startDate) = 10 THEN 1 ELSE 0 END),
FTENov = (CASE WHEN MONTH(startDate) = 11 THEN 1 ELSE 0 END),
FTEDec = (CASE WHEN MONTH(startDate) = 12 THEN 1 ELSE 0 END);
Here is an SQL Fiddle example.

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