SQL return having sum value - mysql

I have a query that checks a group and makes sure that it has more than 1 value under 2
SELECT `tile` FROM TFResults
GROUP BY `tile`
HAVING SUM(CASE WHEN `Place` < 2 THEN 1 ELSE 0 END)> 1 ;
I would like to return the value of sum also but can't seem to get it to work
SELECT `tile`, thesum
FROM TFResults
GROUP BY `tile`
HAVING SUM(CASE WHEN `Place` < 2 THEN 1 ELSE 0 END) as thesum > 1 ;

You define alias names in the select clause
SELECT tile,
SUM(CASE WHEN Place < 2 THEN 1 ELSE 0 END) as thesum
FROM TFResults
GROUP BY tile
HAVING thesum > 1

First you need to move sum part to select statement. And if you need only one column to check then use if instead CASE. Check Below
SELECT tile, SUM(if(Place < 2, 1, 0)) place_sum
FROM TFResults
GROUP BY tile
HAVING place_sum > 1

Just move sum statement to select:
SELECT
`tile`,
SUM(CASE WHEN `Place` < 2 THEN 1 ELSE 0 END) AS thesum
FROM TFResults
GROUP BY `tile`
HAVING thesum > 1 ;

Related

MySQL - join/group concat returning too many items

I've got a simple query which brings up wins, draws and losses in a head-to-head matches table.
SELECT
SUM(CASE WHEN score_w > score_m THEN 1 ELSE 0 END) AS wins_w,
SUM(CASE WHEN score_m > score_w THEN 1 ELSE 0 END) AS wins_m,
SUM(CASE WHEN score_w = score_m THEN 1 ELSE 0 END) AS draws
FROM 6dos7me3xn8
All is well. I get a single row, with the data I need as columns.
Now I want to also pull out a group concat'd list of the most recent three match dates. I tried:
SELECT
SUM(CASE WHEN mn.score_w, 0) > mn.score_m THEN 1 ELSE 0 END) AS wins_w,
SUM(CASE WHEN mn.score_m > mn.score_w THEN 1 ELSE 0 END) AS wins_m,
SUM(CASE WHEN mn.score_w = mn.score_m THEN 1 ELSE 0 END) AS draws,
GROUP_CONCAT(jn.date) AS recent
FROM 6dos7me3xn8 mn
JOIN (SELECT date FROM 6dos7me3xn8 ORDER BY date DESC LIMIT 3) jn
...but the LIMIT is having no effect, seemingly - I get all of the dates group concat'd, not just 3.
I also tried removing the JOIN and replacing the GROUP_CONCAT with
GROUP_CONCAT((SELECT date FROM 6dos7me3xn8 ORDER BY date DESC LIMIT 3)) AS recent
...but that errors with 'Subquery returns more than 1 row.'
I'm sure it's something simple, but what am I doing wrong?
If you are running MySQL 8.0, you can do this with window functions:
select
sum(score_w > score_m) as wins_w,
sum(score_m > score_w) as wins_m,
sum(score_w = score_m) as draws,
group_concat(case when rn <= 3 then date end) as recent
from (
select t.*, row_number() over(order by date desc) rn
from `6dos7me3xn8` t
) t
The subquery ranks records by descending date; we can then use that information in the outer query. Note that you don't need the case expressions: MySQL evaluates true/false conditions as 1/0 in numeric contet.
In earlier versions, the simpler approach is probably a row-limiting subquery:
select
sum(score_w > score_m) as wins_w,
sum(score_m > score_w) as wins_m,
sum(score_w = score_m) as draws,
(select group_concat(date) from (select date from `6dos7me3xn8` order by date desc limit 3) t) as recent
from `6dos7me3xn8`
You are doing a cross join. TO get the most recent three dates, you can use:
FROM (SELECT mn.*, DENSE_RANK() OVER (ORDER BY date desc) as seqnum
FROM 6dos7me3xn8 mn
) mn
WHERE seqnum <= 3
You have no ON clause to specify the relationship between the subquery and the table you're joining it to. So you get a full cross product.
You also need ORDER BY to make it return the 3 most recent dates, not any 3 dates.
SELECT
SUM(CASE WHEN mn.score_w, 0) > mn.score_m THEN 1 ELSE 0 END) AS wins_w,
SUM(CASE WHEN mn.score_m > mn.score_w THEN 1 ELSE 0 END) AS wins_m,
SUM(CASE WHEN mn.score_w = mn.score_m THEN 1 ELSE 0 END) AS draws,
GROUP_CONCAT(jn.date) AS recent
FROM 6dos7me3xn8 mn
JOIN (
SELECT DISTINCT date
FROM 6dos7me3xn8
ORDER BY date DESC
LIMIT 3
) jn ON jn.date = mn.date

Count different values in a column, while doing total and group by different column values

We have a table with data from different nodes and one of the column will have status report as "compliant or non-compliant", sample data as below
I want to filter the table in such a way that if any of the checks on a node shows non compliant, it should be flagged as non-compliant and rest as compliant. Using below query i am able to do it
SELECT COUNT(*) AS total_nodes,
SUM(fully_compliant = 0) AS Non_compliant_nodes,
SUM(fully_compliant = 1) AS compliant_nodes
FROM (
SELECT Node, CASE WHEN SUM(Status = 'Compliant') = COUNT(*) THEN 1 ELSE 0 END AS fully_compliant
FROM your_table GROUP BY Node
)
Now, i want to group and split the result by dept as below, how can i achieve this
I think you're looking for this:
select dept,
count(*) as total_nodes,
sum(case when non_compliant_chk = 0 then 1 else 0 end) as compliant_nodes,
sum(case when non_compliant_chk > 0 then 1 else 0 end) as non_compliant_nodes
from (
select dept,
node,
sum(case when 'Non-Compliant' then 1 else 0 end) as non_compliant_chk
from your_table
group by dept,
node
) v
group by dept;
With few modifications to what Brian suggested, I am able to get the desired result
select dept,
count(*) as total_nodes,
sum(case when non_compliant_chk = 0 then 1 else 0 end) as compliant_nodes,
sum(case when non_compliant_chk > 0 then 1 else 0 end) as non_compliant_nodes
from (
select dept,
node,
COUNT(CASE WHEN Compliance-Status = 'Non-Compliant' THEN 1 END) 'non_compliant_chk'
from table WHERE DOR >= DATE(NOW()) - INTERVAL 7 DAY
group by Dept,
Node
) v
group by Dept;

how to get column count

i have a query like below
select project_task_id,
status_id,
sum(case when StatusID=1 then 1 else 0 end) as task_id=1,
sum(case whenStatusID=2 then 1 else 0 end) as task_id=2,
sum(case when StatusID=3 then 1 else 0 end) as task_id=3,
sum(case when StatusID=4 then 1 else 0 end) as task_id=4,
sum(case when StatusID=5 then 1 else 0 end) as task_id=5,
sum(case when StatusID=6 then 1 else 0 end) as task_id=6,
sum(case when StatusID=7 then 1 else 0 end) as task_id=7,
from"Projects".work_unit_status
group by project_task_id,status_id;
I'm getting the below attached output:
https://i.stack.imgur.com/1wfD1.png
and I want to get the below expected output:
https://i.stack.imgur.com/Zql9z.png
include zero's if the status_id is blank
please any one help on this
Try this: use the addition of all sum column
select project_task_id,status_id,
isnull(sum(case when StatusID=1 then 1 else 0 end),0)+
isnull(sum(case whenStatusID=2 then 1 else 0 end),0) +
isnullsum(case when StatusID=3 then 1 else 0 end),0) +
isnullsum(case when StatusID=4 then 1 else 0 end),0)+
isnullsum(case when StatusID=5 then 1 else 0 end),0) +
isnullsum(case when StatusID=6 then 1 else 0 end),0) +
isnullsum(case when StatusID=7 then 1 else 0 end),0) as count_status
from"Projects".work_unit_status group by project_task_id,status_id
use in with your case
with t1 as (
select project_task_id,
status_id,
sum(case when StatusID in (1,2,3,4,5,6,7) then 1 else 0)
as sum_s
from "Projects".work_unit_status
group by project_task_id,status_id
) ,
t2 as
(
select * from (
select 1 as statusid
union
select 2
union
select 3
union
select 4
union
select 5
union
select 6
union
select 7 ) t
) select t1.project_task_id,
t2.statusid,
case when t1.sum_s>0 or not null
then sum_s else 0 end as total
t2 full join t1 on t2.statusid=t1.status_id
Without knowing the exact table structure I assumed that status_id and statusId refer to the same column. (If they are different columns, we need to use StatusId in the COUNT.)
Based on the expected output, you want to count the status_id and group by project_task_id. To make sure that every status is represented for every task, first, we need to create a subquery of all possible project_task_id/status_id combinations. Then we use that with the aggregate values of the original table.
select
ps.project_task_id,
ps.status_id,
count(w.status_id) as total
from (
select distinct
project_task_id,
s.status_id
from work_unit_status
cross join (select distinct status_id from work_unit_status) s
) ps
left join work_unit_status w
on ps.project_task_id = w.project_task_id and ps.status_id = w.status_id
group by
ps.project_task_id,
ps.status_id
If you really need to hardcode the statuses from 1 to 7, use the query below.
select
ps.project_task_id,
ps.status_id,
count(w.status_id) as total
from (
select distinct
project_task_id,
s.status_id
from work_unit_status
cross join (
select 1 as status_id
union select 2
union select 3
union select 4
union select 5
union select 6
union select 7
) s
) ps
left join work_unit_status w
on ps.project_task_id = w.project_task_id and ps.status_id = w.status_id
group by
ps.project_task_id,
ps.status_id
order by
ps.project_task_id,
ps.status_id

How i can write this query in PostgreSQL?

Original from MySQL. There I want to know how many separate rows with columns by condition:
SELECT
sum(status='waiting'),
sum(source='twitter'),
sum(no_send_before <= '2009-05-28 03:17:50'),
sum(tries <= 20),
count(*)
FROM table_name
*************************** 1. row ***************************
sum(status ='waiting'): 550
sum(source='twitter'): 37271
sum(no_send_before <= '2009-05-28 03:17:50'): 36975
sum(tries <= 20): 36569
count(*): 37271
For a query that is consistent between the two databases, use case:
SELECT sum(case when status='waiting' then 1 else 0 end),
sum(case when source='twitter' then 1 else 0 end),
sum(case when no_send_before <= '2009-05-28 03:17:50' then 1 else 0 end),
sum(case when tries <= 20 then 1 else 0 end),
count(*)
FROM table_name;
For a shorter, Postgres-specific syntax:
SELECT sum((status='waiting')::int),
sum((source='twitter')::int)),
sum((no_send_before <= '2009-05-28 03:17:50'))::int),
sum((tries <= 20))::int),
count(*)
FROM table_name

SQL QUERY- multiple COUNT returns wrong (same) results when using in GROUP BY

I will simplfy this:
I have two SQL expressions which works OK:
First:
select count(*) as number1
from T1
where DATE1>'2012-01-01' and DATE2<'2012-12-31'
Result:13
select count(*) as number2
from T1
where DATE3>DATE2 and CURDATE()>DATE2
Result:5
But when I try to insert those two COUNTS in GROUP BY I am getting as resulyt always 13!!!
SELECT NAME,
COUNT(case when DATE1>'2012-01-01' and DATE2<'2012-12-31' then 1 else 0 end) as number1,
COUNT (case when (DATE3>DATE2 and CURDATE()>DATE2) then 1 else 0 end) as number 2
from T1
I am getting as result:
NAME NUMBER1 NUMBER2
A 5 5
B 4 4
C 4 4
But I should get:
NAME NUMBER1 NUMBER2
A 5 4
B 4 0
C 4 1
So that SUM of columns be 13 and 5 like in first two queries . What am I doing wrong?
Thank you
COUNT(expression) counts not null expressions. You can modify your query by changing the ELSE 0 to ELSE NULL or by removing it (the ELSE NULL is implied at CASE expressions):
SELECT name,
COUNT(CASE WHEN date1 > '2012-01-01' AND date2 < '2012-12-31'
THEN 1 END
) AS number1,
COUNT(CASE WHEN date3 > date2 AND CURDATE() > date2
THEN 1 END
) AS number2
FROM T1
GROUP BY name ;
Do not use count here.Use Sum. If you want to use the count then put null in else instead of 0
try:
SELECT NAME,
(select count(*) from T1 where DATE1>'2012-01-01' and DATE2<'2012-12-31') AS number1,
(select count(*) from T1 where DATE3>DATE2 and CURDATE()>DATE2) AS number2
FROM T1
GROUP BY NAME
Try this:
SELECT name,
SUM(CASE WHEN DATE1>'2012-01-01' AND DATE2<'2012-12-31' THEN 1 ELSE 0 END) AS number1,
SUM(CASE WHEN (DATE3>DATE2 AND CURDATE()>DATE2) THEN 1 ELSE 0 END) AS number2
FROM T1 GROUP BY name