MySQL CASE WHEN where clause causes failure - mysql

I have a complex query that does multiple matches across multiple columns and then orders by relevance.
Everything works fine UNTIL I add WHERE 'rank' > 0
This then returns an empty results set.
If I remove the 'WHERE' statement then I can see all results with the highest matches at the top.
Could someone help me work out 'WHERE' :-D I am going wrong!!
SELECT *, CASE WHEN companyName = 'gfdgfs' THEN 2 ELSE 0 END
+ CASE WHEN companyName LIKE '%gfdgfs%' THEN 1 ELSE 0 END
+ CASE WHEN companyName = 'potato' THEN 2 ELSE 0 END
+ CASE WHEN companyName LIKE '%potato%' THEN 1 ELSE 0 END
+ CASE WHEN address1 = 'gfdgfs' THEN 2 ELSE 0 END
+ CASE WHEN address1 LIKE '%gfdgfs%' THEN 1 ELSE 0 END
+ CASE WHEN address1 = 'potato' THEN 2 ELSE 0 END
+ CASE WHEN address1 LIKE '%potato%' THEN 1 ELSE 0 END
AS rank
FROM clients
WHERE rank > 0
ORDER BY rank
EDIT
I removed the single quotes around the rank word and now get 'unknown column rank in where clause'

Remove single quotes from rank and try. Anyway, I don't think MySQL would support WHERE clause with aliases - check this.
Use HAVING rather than WHERE:
SELECT *, CASE WHEN companyName = 'gfdgfs' THEN 2 ELSE 0 END
+ CASE WHEN companyName LIKE '%gfdgfs%' THEN 1 ELSE 0 END
+ CASE WHEN companyName = 'potato' THEN 2 ELSE 0 END
+ CASE WHEN companyName LIKE '%potato%' THEN 1 ELSE 0 END
+ CASE WHEN address1 = 'gfdgfs' THEN 2 ELSE 0 END
+ CASE WHEN address1 LIKE '%gfdgfs%' THEN 1 ELSE 0 END
+ CASE WHEN address1 = 'potato' THEN 2 ELSE 0 END
+ CASE WHEN address1 LIKE '%potato%' THEN 1 ELSE 0 END
AS rank
FROM clients
HAVING rank > 0
ORDER BY rank

Try this:
SELECT *
FROM (SELECT *, CASE WHEN companyName = 'gfdgfs' THEN 2 ELSE 0 END
+ CASE WHEN companyName LIKE '%gfdgfs%' THEN 1 ELSE 0 END
+ CASE WHEN companyName = 'potato' THEN 2 ELSE 0 END
+ CASE WHEN companyName LIKE '%potato%' THEN 1 ELSE 0 END
+ CASE WHEN address1 = 'gfdgfs' THEN 2 ELSE 0 END
+ CASE WHEN address1 LIKE '%gfdgfs%' THEN 1 ELSE 0 END
+ CASE WHEN address1 = 'potato' THEN 2 ELSE 0 END
+ CASE WHEN address1 LIKE '%potato%' THEN 1 ELSE 0 END
AS rank
FROM clients
) AS A
WHERE rank > 0
ORDER BY rank;

Related

MySQL How to count columns containing specified column value

I have the table xyz
ID day1 day2 day3 day4
1 A A P P
2 A A A P
3 A A A A
4 A P P P
I want to be able to query this and return the ID with the number of columns that have A as their value in that row. So the result would look like this:
ID Count
1 2
2 3
3 4
4 1
Here is a trick you can use involving string concatenation:
SELECT
ID,
CHAR_LENGTH(CONCAT(day1, day2, day3, day4)) -
CHAR_LENGTH(REPLACE(CONCAT(day1, day2, day3, day4), 'A', '')) AS Count
FROM yourTable
ORDER BY ID;
Demo
If you want to count other letters as well, just duplicate the logic I have for the letter A, e.g. for L we can try:
CHAR_LENGTH(CONCAT(day1, day2, day3, day4)) -
CHAR_LENGTH(REPLACE(CONCAT(day1, day2, day3, day4), 'L', ''))
This is simple to accomplish applying case to all columns and usmming them up! Try below:
select id,
case day1 when 'A' then 1 else 0 end +
case day2 when 'A' then 1 else 0 end +
case day3 when 'A' then 1 else 0 end +
case day4 when 'A' then 1 else 0 end `CountA`,
case day1 when 'L' then 1 else 0 end +
case day2 when 'L' then 1 else 0 end +
case day3 when 'L' then 1 else 0 end +
case day4 when 'L' then 1 else 0 end `CountL`,
case day1 when 'P' then 1 else 0 end +
case day2 when 'P' then 1 else 0 end +
case day3 when 'P' then 1 else 0 end +
case day4 when 'P' then 1 else 0 end `CountP`
from Tbl

Calculating Total of the row and finding average using MySQL

I have two tables App and Store
Grouped : It is the count of application that is grouped ie HasGroup =1
NonGrouped : It is the count of application that is not grouped ie HasGroup = 0
Grouped (%) : It is the percentage of application that is grouped ie HasGroup =1
NonGrouped (%) : It is the percentage of application that is not grouped ie HasGroup = 0
AverageNonGrouped (%) : It is the average of grouped application ie (Invidual NonGrouped(%) / total NonGrouped(%))*100. example for ABC it is (75/ 165)*100 = 45.45, similarly for XYZ it is (50/ 165)*100 = 30.30. Here 165 is the sum of 75+50+40
My query is as given below
SELECT
AppName,
SUM( CASE HasGroup WHEN 1 THEN 1 ELSE 0 END ) AS Grouped,
SUM( CASE HasGroup WHEN 0 THEN 1 ELSE 0 END ) AS NonGrouped,
ROUND(((SUM( CASE HasGroup WHEN 1 THEN 1 ELSE 0 END ) /
(SUM( CASE HasGroup WHEN 0 THEN 1 ELSE 0 END ) +
SUM( CASE HasGroup WHEN 1 THEN 1 ELSE 0 END )))*100), 2) AS GroupedPercentage,
ROUND(((SUM( CASE HasGroup WHEN 0 THEN 1 ELSE 0 END ) /
(SUM( CASE HasGroup WHEN 0 THEN 1 ELSE 0 END ) +
SUM( CASE HasGroup WHEN 1 THEN 1 ELSE 0 END )))*100), 2) AS NonGroupedPercentage
FROM
Apps
INNER JOIN Store
ON (Apps.Store = Store.Store)
AND AppName !='' GROUP BY AppName
I am able to find the columns except AverageNonGrouped (%) since I don't know how to get total NonGrouped(%), Can anyone please help me on this
It's big query, but it does the job (i've tested on a dataset localy)
SELECT
AppName,
SUM( CASE HasGroup WHEN 1 THEN 1 ELSE 0 END ) AS Grouped,
SUM( CASE HasGroup WHEN 0 THEN 1 ELSE 0 END ) AS NonGrouped,
ROUND(((SUM( CASE HasGroup WHEN 1 THEN 1 ELSE 0 END ) /
(SUM( CASE HasGroup WHEN 0 THEN 1 ELSE 0 END ) +
SUM( CASE HasGroup WHEN 1 THEN 1 ELSE 0 END )))*100), 2) AS GroupedPercentage,
ROUND(((SUM( CASE HasGroup WHEN 0 THEN 1 ELSE 0 END ) /
(SUM( CASE HasGroup WHEN 0 THEN 1 ELSE 0 END ) +
SUM( CASE HasGroup WHEN 1 THEN 1 ELSE 0 END )))*100), 2) AS NonGroupedPercentage,
ROUND(((SUM( CASE HasGroup WHEN 0 THEN 1 ELSE 0 END ) /
(SUM( CASE HasGroup WHEN 0 THEN 1 ELSE 0 END ) +
SUM( CASE HasGroup WHEN 1 THEN 1 ELSE 0 END )))*100), 2) /
(SELECT SUM(NonGroupedPercentage)
FROM (
SELECT
ROUND(((SUM( CASE HasGroup WHEN 0 THEN 1 ELSE 0 END ) /
(SUM( CASE HasGroup WHEN 0 THEN 1 ELSE 0 END ) +
SUM( CASE HasGroup WHEN 1 THEN 1 ELSE 0 END )))*100), 2) AS NonGroupedPercentage
FROM
apps
INNER JOIN store
ON (apps.Store = store.Store)
AND AppName !=''
GROUP BY AppName
) AS total) *100 AS AverageNonGroupedPercentage
FROM
apps
INNER JOIN store
ON (apps.Store = store.Store)
AND AppName !=''
GROUP BY AppName

MySQL SUM with CASE choose latest record by date

I've got the SUM CASE statements working properly. The issue is that I have multiple records with similar criteria, so I'd like to select the latest record by date.
SELECT
SUM(CASE WHEN planning like 'Rotation%' THEN 1 ELSE 0 END +
CASE WHEN assessmentanddata like 'Collects%' THEN 1 else 0 END +
CASE WHEN path like 'Same%' THEN 1 else 0 END +
CASE WHEN place like 'Move%' THEN 1 else 0 END +
CASE WHEN pace like 'Timer%' THEN 1 else 0 END +
CASE WHEN classroommanagement like 'Restating%' THEN 1 else 0 END +
CASE WHEN teacherrole like 'Mini%' THEN 1 else 0 END +
CASE WHEN studentengagement like 'Follow%' THEN 1 else 0 END +
CASE WHEN studentcollaboration like 'Collects%' THEN 1 else 0 END +
CASE WHEN technology like 'Technology%' THEN 1 else 0 END) AS p1
from ruberic where schoolId = 1
A sample from the table will be these 3 columns of DATE, SCHOOLID, and TEACHERID:
2016-12-05 1 1 -> This record will be fine
2016-12-05 1 4 -> Select only this when compared with the record below
2016-12-05 1 4
Building on what I see (I don't see the field name for date so assumed date)
This uses a correlates subquery and an exists statement to identify the max(date) for each teacherID and school and then limits the main dataset by this subset through the coloration.
SELECT
SUM(CASE WHEN planning like 'Rotation%' THEN 1 ELSE 0 END +
CASE WHEN assessmentanddata like 'Collects%' THEN 1 else 0 END +
CASE WHEN path like 'Same%' THEN 1 else 0 END +
CASE WHEN place like 'Move%' THEN 1 else 0 END +
CASE WHEN pace like 'Timer%' THEN 1 else 0 END +
CASE WHEN classroommanagement like 'Restating%' THEN 1 else 0 END +
CASE WHEN teacherrole like 'Mini%' THEN 1 else 0 END +
CASE WHEN studentengagement like 'Follow%' THEN 1 else 0 END +
CASE WHEN studentcollaboration like 'Collects%' THEN 1 else 0 END +
CASE WHEN technology like 'Technology%' THEN 1 else 0 END) AS p1
FROM
ruberic R1
WHERE
schoolId = 1
AND EXISTS (SELECT Null
FROM ruberic r2
WHERE R2.SchoolID = R1.SchoolID
AND R2.TeacherID = R1.TeacherID
GROUP BY SchoolID, TeacherID
HAVING R1.Date = MAX(R2.Date) )

How to count non null fields?

I need to get the count of fields where the value is not null.
My table
city id_no no1 no2 no3
chn A12 2158
chn A13 8181 8182 8183
chn A14 19138
I need to get the count of fields set for no1, ..., no3
My query
SELECT
count(id_no) as total_id,
(count(no1) +
count(no2) +
count(no3)) as c_count
FROM table
WHERE city='chn';
My output
total_id c_count
3 9
Expected:
total_id c_count
3 5
I am expecting 5 instead of 9, since 5 fields are not null.
OR you can simply do this to avoid NULL or ' ' data
SELECT
count(id_no) as total_id,
(count(CASE WHEN no1 > 0 THEN no1 ELSE NULL END) +
count(CASE WHEN no2 > 0 THEN no2 ELSE NULL END) +
count(CASE WHEN no3 > 0 THEN no3 ELSE NULL END)) as c_count
FROM table
WHERE city='chn';
SELECT
count(id_no) as total_id,
(case when count(no1)='' or count(no1) is null then 0 else count(no1) end +
case when count(no2)='' or count(no2) is null then 0 else count(no2) end +
case when count(no3)='' or count(no3) is null then 0 else count(no3) end +
case when count(no4)='' or count(no4) is null then 0 else count(no4) end +
case when count(no5)='' or count(no5) is null then 0 else count(no5) end +
case when count(no6)='' or count(no6) is null then 0 else count(no6) end +
case when count(no7)='' or count(no7) is null then 0 else count(no7) end +
case when count(no8)='' or count(no8) is null then 0 else count(no8) end +
case when count(no9)='' or count(no9) is null then 0 else count(no9) end +
case when count(no10)='' or count(no10) is null then 0 else count(no10) end
) as c_count
FROM table
WHERE city='chn';
I am getting same output as you want please check here i provide my screenshot
SELECT count(id_no) as total_id,
count(CASE WHEN `nol`!="" THEN 1 END) as no1
FROM `table` where city='chn'
try like this
select count(distinct a.`id_no`),count(*) from
(
select `id_no`,`no1` as `non` from table WHERE city='chn'
union all
select `id_no`,`no2` as `non` from table WHERE city='chn'
union all
select `id_no`,`no3` as `non` from table WHERE city='chn'
)a where a.`non` is not null

Using CASE statement in SUM() In Stored Procedure

Here is my code:
BEGIN
SELECT SUM(
CASE WHEN first_name > '' THEN 1 ELSE 0 END AS a
CASE WHEN last_name > '' THEN 1 ELSE 0 END AS b,
CASE WHEN country > '' THEN 1 ELSE 0 END AS c,
CASE WHEN state > '' THEN 1 ELSE 0 END AS d,
CASE WHEN city > '' THEN 1 ELSE 0 END AS e)
AS total
FROM employee_profile
WHERE id = user_id_in;
END
This generates the following error:
you have an error in your SQL syntax check the manual that corresponds to your MySQL server version for the right syntax to use near xxx error for the first line.
Can anyone help with the correct syntax for this, please?
MySQL Server version: 5.5.8
SUM takes a single argument (/ column) which it sums across multiple rows, not multiple arguments (/ columns) for a single row, this is why it's not working.
This should work:
SELECT (CASE WHEN first_name > '' THEN 1 ELSE 0 END +
CASE WHEN last_name > '' THEN 1 ELSE 0 END +
CASE WHEN country > '' THEN 1 ELSE 0 END +
CASE WHEN state > '' THEN 1 ELSE 0 END +
CASE WHEN city > '' THEN 1 ELSE 0 END) AS total
FROM employee_profile
WHERE id = user_id_in;
Try this query this will suerly help you..
SELECT SUM(
CASE
WHEN first_name = '' THEN '1'
WHEN last_name = '' THEN '1'
WHEN country = '' THEN '1'
WHEN state = '' THEN '1'
ELSE '0'
END) AS total
FROM employee_profile
WHERE id = user_id_in;