SQL GROUP BY statement can only use number to group? - mysql

I am learning SQL now and I am kind of confused when encountering a query like this:
SELECT CASE
WHEN url like '%abc.com%'THEN 'abc'
When url like '%def.com%'THEN 'def'
When url like '%smiley.com%' THEN 'Smiley'
Else 'others'
End AS 'sites', count(*)
FROM websites_sources
GROUP BY 1;
The query above works correctly, but only if the GROUP BY Statement uses 1. If I write Group BY 'sites', the result only shows 'others' and the total count of ALL rows (instead of the count for 'others' only and other sites).
My question is, so for GROUP BY Statement we can only use number to indicate grouping, and not the name of the column?
Thanks for your help!

Only use single quote for string and date constants. Never use single quotes for column aliases. You'll just confuse yourself.
Try this:
SELECT (CASE WHEN url like '%abc.com%' THEN 'abc'
WHEN url like '%def.com%' THEN 'def'
WHEN url like '%smiley.com%' THEN 'Smiley'
ELSE 'others'
END) AS sites,
count(*)
FROM websites_sources
GROUP BY sites;
You are grouping by the string 'sites', which is a constant, not the column named sites.

Related

Using fetched Column value as next parameter for evaluation/comparing in next 'IF' or 'CASE' clause in MYSQL SELECT query

I am trying to create a Flow Control Function query on one of my mysql database. That can fetch some data based on previously fetched column values, before sharing my current query, I am explaining what i am trying to achieve.
As you can see in the below SELECT QUERY the result of first IF CLAUSE lead_id has been used as a parameter in WHERE CLAUSE on third IF CLAUSE and that works perfectly, similarly the result of 3rd IF CLAUSE Cont_id has been used in fourth IF CLAUSE as a WHERE CLAUSE parameter, and that also works as desired, but when we use these returned values lead_id and Cont_id of IF CLAUSES for comparing a value in either IF CLAUSE or CASE CLAUSE, it doesn't work, can anyone help how to achieve this by using a different approach?
My query is like this..
SELECT *,
IF(tte.task_id>0, (SELECT mt.lead_id FROM mt WHERE mt.id=tte.task_id), 'NA') AS lead_id,
IF(tte.task_id>0, (SELECT mt.assigned_to_staff_id FROM mt WHERE mt.id=tte.task_id), 'NA') AS staff_id,
IF(tte.task_id>0, (SELECT leads.contact_id FROM leads WHERE leads.id=lead_id),'NA') AS Cont_id,
IF(tte.task_id>0, (SELECT contacts.Name FROM contacts WHERE contacts.id=Cont_id),'NA') AS PC_Name,
CASE WHEN tte.task_id>0 THEN (SELECT contacts.Name AS LC_Name FROM contacts WHERE contacts.id=PC_id) ELSE 'NA' END,
FROM tte ORDER BY request_log_time DESC;
I want to use returned values lead_id and Cont_id of IF CLAUSES for comparing a value in either IF CLAUSE like this:
IF(Cont_id>0, (SELECT contacts.Name FROM contacts WHERE contacts.id=Cont_id),'NA') AS PC_Name
or CASE CLAUSE like this:
CASE WHEN Cont_id>0 THEN (SELECT contacts.Name AS LC_Name FROM contacts WHERE contacts.id=Cont_id) ELSE 'NA' END

How to combine some similar pattern data in one column of mysql, to get the count?

I have a table like below
From this table, I want to get the counts of SearchParams, which I tried like this:
But I want all the data which is matching the pattern "TVE-xxxx" should be combined as "TVE" and the count.
Please help.
Use a CASE statement to determine the value on which you group by:
select
case when searchParam like 'TVE-%' then 'TVE' else searchParam end groupParam,
count(*) counter
from careinsight.testtable
group by groupParam
To filter data with pattern "TVE-xxx" , use below query
select name,count(name)
from tblName
where name REGEXP '^TVE\-[a-zA-Z]{3}$'
group by name
If you have known differences in pattern, you can use CASE/WHEN to summarize your output as below. This case you have to know the list of value may come for one group like 'Account' and you need to put them in the list of IN for the CASE statement.
SELECT
CASE
WHEN searchParam IN ('AccountSVNC','AccountSVNC') THEN 'Account'
WHEN searchParam IN ('TVE-ABC','TVE-CDE','TVE-MFG') THEN 'TVE'
ELSE searchParam
END searchParam,
COUNT(searchParam)
FROM your_table
GROUP BY
CASE
WHEN searchParam IN ('AccountSVNC','AccountSVNC') THEN 'Account'
WHEN searchParam IN ('TVE-ABC','TVE-CDE','TVE-MFG') THEN 'TVE'
ELSE searchParam
END

How to get Count from a Result of MySql Query where each Result is a Different Table itself?

I've a ResultSet of a Mysql Query something like this :-
select concat(category_name,subcategory_name) from category
which is returning Results something like this :- -
MovieComedyMovies CarsSportsCars ShowsComedyShows
These 3 results are different tables itself. I want to perform Count() on these tables which I'm getting in results that is- to check whether these tables contains any data or not.
P.S - I'm using MySQl 5.6
If I understand your comment correctly you can write a subquery on select clause, like this.
SELECT (SELECT COUNT(*) FROM MovieComedyMovies) AS MovieComedyMovies,
(SELECT COUNT(*) FROM CarsSportsCars) AS CarsSportsCars
But from your question, you might want to do this.
CASE WHEN with SUM function.
select SUM(CASE WHEN concat(category_name,subcategory_name) = 'MovieComedyMovies' THEN 1 ELSE 0 END),
SUM(CASE WHEN concat(category_name,subcategory_name) = 'CarsSportsCars' THEN 1 ELSE 0 END)
from category
Edit
From your comment I guessed you can try this.
select concat(category_name,subcategory_name),count(*)
from category
Group by concat(category_name,subcategory_name)
I'm copying your example query for historical purposes:
select concat(category_name,subcategory_name) from category
Assuming that's the query that still draws data:
SELECT count(Name) as Total, Name
FROM (
select concat(category_name,subcategory_name) as Name from category
) data
group by Name
Something along those lines. If you can build a fiddle with an MCVE you might get a more specific answer.

Count number of times a value occurs in a case statement

I've looked all over the site for counting the number of times a value occurs in a query and found answers but nothing addressing it in a case statement.
here is the query I am using that returns results but the results should be higher...the results are in the 70's but should be double that number.
query:
select count(case when field#1 like "Y" then "1" else null end) as column name
from db
where datefield like '2015-04%'
To accomplish something like this, it's more helpful to use conditional aggregation.
This means, instead of using a case statement to sum items, you just put the condition in the SUM() function:
SELECT SUM(field1 LIKE '%y%')'
...
If you don't want to use the conditional aggregation approach, and prefer to use CASE, you'll need to use SUM() instead of COUNT() like this:
SELECT SUM(CASE WHEN field1 LIKE '%y%' THEN 1 ELSE 0 END) AS counts
...

MySQL LIKE with range doesn't work

I've got a database table mytable with a column name in Varchar format, and column date with Datetime values. I'd like to count names with certain parameters grouped by date. Here is what I do:
SELECT
CAST(t.date AS DATE) AS 'date',
COUNT(*) AS total,
SUM(LENGTH(LTRIM(RTRIM(t.name))) > 4
AND (LOWER(t.name) LIKE '%[a-z]%')) AS 'n'
FROM
mytable t
GROUP BY
CAST(t.date AS DATE)
It seems that there's something wrong with range syntax here, if I just do LIKE 'a%' it does count properly all the fields starting with 'a'. However, the query above returns 0 for n, although should count all the fields containing at least one letter.
You write:
It seems that there's something wrong with range syntax here
Indeed so. MySQL's LIKE operator (and SQL generally) does not support range notation, merely simple wildcards.
Try MySQL's nonstandard RLIKE (a.k.a. REGEXP), for fuller-featured pattern matching.
I believe LIKE is just for searching for parts of a string, but it sounds like you want to implement a regular expression to search for a range.
In that case, use REGEXP instead. For example (simplified):
SELECT * FROM mytable WHERE name REGEXP "[a-z]"
Your current query is looking for a string of literally "[a-z]".
Updated:
SELECT
CAST(t.date AS DATE) AS 'date',
COUNT(*) AS total,
SUM(LENGTH(LTRIM(RTRIM(t.name))) > 4
AND (LOWER(t.name) REGEXP '%[a-z]%')) AS 'n'
FROM
mytable t
GROUP BY
CAST(t.date AS DATE)
I believe you want to use WHERE REGEXP '^[a-z]$' instead of LIKE.
You have regex in your LIKE statement, which doesn't work. You need to use RLIKE or REGEXP.
SELECT CAST(t.date AS DATE) AS date,
COUNT(*) AS total
FROM mytable AS t
WHERE t.name REGEXP '%[a-zA-Z]%'
GROUP BY CAST(t.date AS DATE)
HAVING SUM(LENGTH(LTRIM(RTRIM(t.name))) > 4
Also just FYI, MySQL is terrible with strings, so you really should trim before you insert into the database. That way you don't get all that crazy overhead everytime you want to select.