mysql SELECT columns but use WHERE to only one - mysql

I have this query:
SELECT i.d, COUNT(id) AS dr, COUNT(id2) AS dn, SUM(eq) AS eq_sum, COUNT(thx) AS thx_count
FROM dsd
INNER JOIN
(
SELECT COUNT(id) AS d FROM ds
) i
Now I want to use WHERE only to column thx like WHERE thx="y" , so that it will count only all values with "y".
But If I just add WHERE at the end of the query it will affect other columns as well which I don't want to.
How to do this?

Then change your COUNT(thx) AS thx_count to below using CASE expression like
COUNT(CASE WHEN thx = 'y' THEN 1 ELSE 0 END) AS thx_count
(OR)
SUM(CASE WHEN thx = 'y' THEN 1 ELSE 0 END) AS thx_count

Related

Vertical column result to horizontal

I need put a column result in to horizontal position, like SUM(CASE WHEN status = 'On Hold' THEN 1 ELSE 0 END) AS 'word' do, I tried a subquery and alias AS too but I didn't have had success. I think that JOIN is to multiple tables, and UNION to get results in same column.
I'm using this page as reference
https://www.mysqltutorial.org/mysql-case-function/
mysql Table: phpvms_pireps
pilotid|flightnum|submitdate|accepted
My sql code:
SELECT DISTINCT `phpvms_pireps`.`pilotid`
, `phpvms_pireps`.`accepted`
, `phpvms_pireps`.`flightnum`
, `phpvms_pireps`.`submitdate`
FROM phpvms_pireps
WHERE ((`phpvms_pireps`.`flightnum` in ('A-1', 'A-2', 'A-3', 'A-4')))
AND submitdate BETWEEN '2020-04-09' AND '2020-04-11'
ORDER
BY `phpvms_pireps`.`pilotid` ASC
The result:
And I want to achieve this:
I'm using php/html, How I can get that result?
Thank you very much!
You are describing a pivot table. Consider using conditional aggregation:
select
pilotid,
max(case when flightnum = 'A-1' then accepted end) a1,
max(case when flightnum = 'A-2' then accepted end) a2,
max(case when flightnum = 'A-3' then accepted end) a3,
max(case when flightnum = 'A-4' then accepted end) a4
from phpvms_pireps
where
flightnum in ('A-1', 'A-2', 'A-3', 'A-4')
and submitdate between '2020-04-09' and '2020-04-11'
group by pilotid
order by pilotid

SQL count when value = 1

I'm doing a select on two tables with this:
SELECT m.torneio, m.deck, m.top, m.lugar, sum( m.quantidade ) AS quantidade, m.formato AS formato, q.quantidade AS qtorneio, t.season AS season, sum( m.top ) AS totaltops, count( m.lugar = '1' ) AS venceu
FROM `metagame` AS m, quantidade AS q, torneios AS t
WHERE m.torneio = t.nome
AND m.torneio = q.nome
GROUP BY m.deck
My problem is that venceu is counting all instances instead of only the ones when lugar = 1. Why is that?
tried with sum() too with no good results too. How can i fix this?
I am surprised that count( m.lugar = '1' ) syntaxs but it does and returns the sames as count(*). You should probably change it to sum(case when lugar = 1 else 0 end) as venceu. You should also look closely at the group by to be sure it works as you expect (i suspect not).
count(x) does not accept an expression.
It's only counting how many times x is returned.
What you should do is check if m.lugar is 1 and yes add one to the counter else do nothing.
Inline checks can be done like so:
case when m.lugar = '1' then 1 else 0 end
Then add all the one you gets :
sum(case when m.lugar = '1' then 1 else 0 end)
Your final query should look like this:
SELECT
m.torneio,
m.deck,
m.top,
m.lugar,
sum( m.quantidade ) AS quantidade,
m.formato AS formato,
q.quantidade AS qtorneio,
t.season AS season,
sum( m.top ) AS totaltops,
sum(case when m.lugar = '1' then 1 else 0 end) AS venceu
FROM
`metagame` AS m,
quantidade AS q,
torneios AS t
WHERE
m.torneio = t.nome
AND m.torneio = q.nome
GROUP BY
m.deck
If I understand your question you can use this:
sum(case when m.lugar = '1' then 1 else 0 end)
or you can try having clause
SELECT column_name(s)
FROM table_name
WHERE condition
GROUP BY column_name(s)
HAVING condition
ORDER BY column_name(s);

how to perform a count on a column where a value is X

is there a way of performing a count operation with SQL where the column equals X
and ideally a separate count for when the same column equals Y and again for Z?
SELECT yourcolumn, COUNT(*) AS cnt
FROM yourtable
WHERE yourcolumn IN ('X', 'Y', 'Z')
GROUP BY yourcolumn
Something like this ?
select
sum(case when val = 'x' then 1 else 0 end) as countX
,sum(case when val = 'y' then 1 else 0 end) as countY
,sum(case when val = 'z' then 1 else 0 end) as countZ
from table
I believe the following (shorter) statement should work for MySQL:
SELECT COUNT(val='X'), COUNT(val='Y'), COUNT(val='Z') FROM ...
I would suggest the following:
SELECT YourColumn, COUNT(<Any Column of your table>)
FROM YourTable
GROUP BY YourColumn

Combing two queries while using group by

Having some trouble figuring out the logic to this. See the two queries below:
Query 1:
SELECT cId, crId, COUNT(EventType)
FROM Data
WHERE EventType='0' OR EventType='0p' OR EventType='n' OR EventType = 'np'
GROUP BY crId;
Query 2:
SELECT cId, crId, COUNT(EventType) AS Clicks
FROM Data
WHERE EventType='c'
GROUP BY crId;
Was just wondering if there was a way to make the column that I would get at the end of query 2 appear in query 1. Since the where statements are different, not really sure where to go, and any subquery that I've wrote just hasn't worked.
Thanks in advance
SELECT cId, crId,
SUM(CASE WHEN EventType='0' OR EventType='0p' OR EventType='n' OR EventType = 'np' THEN 1 ELSE 0 END) AS Count_1,
SUM(CASE WHEN EventType='c' THEN 1 ELSE 0 END) AS Count_2
FROM Data
WHERE EventType IN ('0','0p','n','np','c')
GROUP BY crId;
You can join the two, using the second as a correlated subquery.
SELECT
Data.cId,
Data.crId,
COUNT(EventType) AS event_type_count,
click_counts.Clicks
FROM
Data
/* Correlated subquery retrieves the Clicks (EventType 'c') per cId */
LEFT JOIN (
SELECT cId, crId, COUNT(EventType) AS Clicks
FROM Data
WHERE EventType='c'
GROUP BY crId
) AS click_count ON Data.cId = click_count.cId AND Data.crId = click_count.crId
/* OR chain replaced with IN() clause */
WHERE Data.EventType IN ('0','0p','n','np')
/* This GROUP BY should probably also include Data.cId... */
GROUP BY Data.crId;
You can do this all querying from the table once and using CASE statements.
SELECT cId, crId,
SUM(CASE WHEN EventType IN ('0', '0p', 'n', 'np') THEN 1 ELSE 0 END) as events,
SUM(CASE WHEN EventType = 'c' THEN 1 ELSE 0 END) as clicks
FROM Data
WHERE EventType IN ('0', '0p', 'n', 'np', 'c')
GROUP BY crId;
You want to use IN?
SELECT cId, crId, COUNT(EventType) as Clicks
FROM Data
WHERE EventType IN ('0','0p','n','np','c')
GROUP BY crId;
:) PUtting myself in right direction ;)
sqlfiddle demo
select id, crid,
count(case when type <> 'c'
then crid end) count_others,
count(case when type ='c'
then crid end) count_c
from tb
group by crid
;

get count of two table fields in one query

I am trying to get the count of females and males in the gender field of a table.
Is there a way to get the count of each in one query?
Something like:
select * from table count(where gender = 'm') as total_males, count(where gender = 'f') as total_females;
or will it require two queries?
select count(*) from table where gender = 'm';
select count(*) from table where gender = 'f';
This is basically a PIVOT. MySQL does not have a pivot so you can use an aggregate function with a CASE statement to perform this:
select
sum(case when gender = 'm' then 1 else 0 end) Total_Male,
sum(case when gender = 'f' then 1 else 0 end) Total_Female
from yourtable
See SQL Fiddle with Demo
Or using COUNT:
select
count(case when gender = 'm' then 1 else null end) Total_Male,
count(case when gender = 'f' then 1 else null end) Total_Female
from yourtable;
See SQL Fiddle with Demo
Something like this will work:
SELECT SUM(IF(t.gender='m',1,0)) AS total_males
, SUM(IF(t.gender='f',1,0)) AS total_females
FROM mytable t
The "trick" here is that we are using a conditional test to return either a 0 or a 1 for each row, and then adding up the 0's and 1's. To make this a little more clear, I am using the SUM aggregate function rather than COUNT, although COUNT could be used just as easily, though we'd need to return a NULL in place of the zero.
SELECT COUNT(IF(t.gender='m',1,NULL)) AS total_males
, COUNT(IF(t.gender='f',1,NULL)) AS total_females
FROM mytable t
Consider that the two expressions in the SELECT list of this query:
SELECT COUNT(1)
, SUM(1)
FROM mytable t
Will return the same value.
If you want to avoid the MySQL IF function, this can also be done using the ANSI SQL CASE expression:
SELECT SUM( CASE WHEN t.gender = 'm' THEN 1 ELSE 0 END )) AS total_males
, SUM( CASE WHEN t.gender = 'f' THEN 1 ELSE 0 END )) AS total_females
FROM mytable t
select sum(case when gender='m' then 1 else null end) as total_males, sum(case when gender='f' then 1 else null end) as total_females from ...
Should work just fine!
If your only issue is to avoid two queries, you can always write two queries as subselects of one query.
Select (select 1 from dual) as one, (select 2 from dual) as two from dual
This would work for your scenario, too.