Counting records that contain letters given in (SQL) - sql

I have to count records containing given letters, for example column A will contain count of records containing 'a' or 'A', and for E it will be count of records containing 'e' or 'E'. Is there any way to do this by only using grouping functions?
I can do this by using subqueries, but we had this task in class before learning subqueries and I have no idea how to do this by grouping.
The result of the code below that I want to achieve by using grouping:
select
(select count(*) from table where lower(name) like '%a%') as a,
(select count(*) from table where lower(name) like '%e%') as e
from dual;

you can use count + case to avoid repeating full-table query select
select count(case when lower(name) like '%a%' then 1 end) as a
,count(case when lower(name) like '%e%' then 1 end) as e
from Table

The proper expression uses sum():
select sum(case when lower(name) like '%a%' then 1 else 0 end) as num_a,
sum(case when lower(name) like '%e%' then 1 else 0 end) as num_e
from t;
You can also use regular expressions (although they are probably more expensive than like for this purpose):
select sum(case when regexp_like(name, '[aA]') then 1 else 0 end) as num_a,
sum(case when regexp_like(name, '[eE]') then 1 else 0 end) as num_e
from t;

Related

SQL Case When Statement for Id with multiple rows

I have a table like so
Id Code
1 03J0
1 0304
1 03HI
2 033I
2 03J5
3 03J4
4 030H
I want to do a case when statement, when there is any occurrence where the Id has a Code that is like '%03J' then Happy otherwise Sad. How do I do this when an Id has multiple rows of different codes?
Intended output
Id Emotion
1 Happy
2 Happy
3 Happy
4 Sad
Is this what you want?
select id,
(case when sum(case when code like '03J%' then 1 else 0 end) > 0 then 'Happy' else 'Sad' end) as emotion
from t
group by id;
Using the ordering of strings, you can simplify this to:
select id,
min(case when code like '03J%' then 'Happy' else 'Sad' end) as emotion
from t
group by id;
Here is a db<>fiddle.
Using self-join. Judging from your sampple data, I think you want '03J%' instead of '%03J'
select distinct a.id, case when b.code is not null then 'Happy' else 'Sad' end as emotion
from mytable a
left join mytable b on a.id=b.id and b.code like '03J%';

Is there a way to contruct this kind of result using group by in sql?

I have a table which consists of data where in I'm having trouble counting the corresponding rows.
Here is the sample table:
I am expecting an output like this:
You can do conditional aggregation:
select
sum(case when result = 'X' then 1 else 0 end) count_x,
sum(case when result is null then 1 else 0 end) count_blank
from mytable
I assume that by blank you mean null. If not, then you can change the condition in the second sum() from result is null to result = ''.
If you are running MySQL, this can be shortened a little:
select
sum(result = 'X') count_x,
sum(result is null) count_blank
from mytable

SQL query - group by string prefix

I'm struggling with a grouping query.
I have simple table named CarParts where some car elements stored in it.
Some of those elements are available (with Type prefix "05") and some are blocked (Type prefix "01").
I want to write select query that would group my table CarParts by SerialNr and Type as shown below on the right side.
Do you want conditional aggregation?
select serialnr, name,
sum(case when type like '%-05' then amount else 0 end) as [05-available],
sum(case when type like '%-01' then amount else 0 end) as [01-blocked]
from carparts
group by serialnr, name;
You can use PIVOT to get your desired result as below-
SELECT SerialNr,
ISNULL([05-Available],0) [05-Available],
ISNULL([01-Available],0) [01-Available],
Name
FROM
(
SELECT SerialNr,Amount,Name,RIGHT( Type,2) +'-Available' AS P_Column
FROM CarParts
) AS P
PIVOT
(
SUM(Amount)
FOR P_Column IN ([01-Available],[05-Available])
) AS PVT
you can use case when
select SerialNr,Name,
sum(case when right([Type],2)='01' then amount else 0 end) as blocked_01
sum(case when right([Type],2)='05' then amount else 0 end) as availabe_05
from tbale_name group by SerialNr,Name
select SerialNr,
sum(case when Type like '%-05' then Amount else 0 end) as '05-available',
sum(case when Type like '%-01' then Amount else 0 end) as '01-blocked',
Name
from carparts
group by SerialNr, Name

SQL Server - count how many names have 'A' and how many have 'E'

I have problem with SQL query.
I have names in column Name in Table_Name, for example:
'Mila', 'Adrianna' 'Emma', 'Edward', 'Adam', 'Piter'
I would like to count how many names contain the letter 'A' and how many contain the letter 'E'.
The output should be:
letter_A ( 5 )| letter_E (3)
I tried to do this:
SELECT Name,
letter_A = CHARINDEX('A', Name),
letter_E = CHARINDEX('E', Name)
FROM Table_Name
GROUP BY Name
HAVING ( CHARINDEX('A', Nazwisko) != 0
OR ( CHARINDEX('E', Nazwisko) ) != 0 )
My query only shows if 'A' or 'E' is in Name :/
Can anyone help? :)
You can use conditional aggregation:
select sum(case when Nazwisko like '%A%' then 1 else 0 end) as A_cnt,
sum(case when Nazwisko like '%E%' then 1 else 0 end) as E_cnt
from table_name
where Nazwisko like '%A%' or Nazwisko like '%E%';
You just need to aggregate if you only need the counts.
select
sum(case when charindex('a',name) <> 0 then 1 else 0 end) as a_count
,sum(case when charindex('e',name) <> 0 then 1 else 0 end) as e_count
from table_name
;WITH CTE
AS (SELECT NAME
FROM (VALUES ('MILA'),
('ADRIANNA'),
('EMMA'),
('EDWARD'),
('ADAM'),
('PITER'))V(NAME)),
CTE_NAME
AS (SELECT COUNT(NAME_A) NAME_A,
COUNT(NAME_E) NAME_E
FROM (SELECT CASE
WHEN NAME LIKE '%A%' THEN NAME
END NAME_A,
CASE
WHEN NAME LIKE '%E%' THEN NAME
END NAME_E
FROM CTE
GROUP BY NAME)A)
SELECT *
FROM CTE_NAME

SQL statement using case, like, and having

I am using an Oracle based system.
How do you use like, having, and a case statement together?
I am basically trying to list all of the unique individuals that are found in a transactional table that have more than 4 "Class A" transactions, or more than 1 "Class B" transactions. The reason why I want to use like is because the only way to diferentiate between transaction classes is by using a like statement in the transaction type column.
For example, there are many transaction types, but only "Class A" have '%ABC%' as part of their transaction type, and "Class B" are all the other types that do not have '%ABC%' in their transaction type column.
So again, I want my query to return only the indiv ids that have more than 4 "Class A" Transactions, or 1 "Class B" transaction.
here is what I have so far:
select tt.indiv_id, count(*) from transactiontable tt
group by tt.indiv_id
case when tt.tran_type like '%ABC'
having count(*) > 4
else
having count(*)>1.
I have searched a good bit on the site and I have not found an example using all of these functions together.
select tt.indiv_id,
count(case when tt.tran_type like '%ABC' then 1 end) as ClassACount,
count(case when tt.tran_type not like '%ABC' then 1 end) as ClassBCount
from transactiontable tt
group by tt.indiv_id
having count(case when tt.tran_type like '%ABC' then 1 end) > 4
or count(case when tt.tran_type not like '%ABC' then 1 end) > 1
Try this
select tt.indiv_id, count(*)
from transactiontable tt
group by tt.indiv_id, tt.tran_type
having count(*) > case when tt.tran_type like '%ABC' then 4 else 1 end
Your query is close. You want to keep track of each transaction type separately in the having clause:
select tt.indiv_id, count(*)
from transactiontable tt
group by tt.indiv_id
having sum(case when tt.tran_type like '%ABC%' then 1 else 0 end) > 4 or
sum(case when tt.tran_type not like '%ABC%' then 1 else 0 end) > 1