I have been trying to print column names based on condition and value.
My problem is this
If two all the columns in the two rows like for data x and y have value yes the it should print those column names otherwise not
My code:
select 'A' from world.city where A = 'yes' AND data=y and data=x union all
select 'B' from world.city where B= 'yes' AND data=y and data=x union all
select 'C' from world.city where C= 'yes' AND data=y and data=x union all
select 'D' from world.city where D= 'yes' AND data=y and data=x union all
select 'E' from world.city where E= 'yes' AND data=y and data=x;
It is not giving perfect results.
Do a sum and union all then filter the rows with sum('yes') is equal to 2. See below.
select colname
from (
select 'A' as colname,sum(case when A='yes' then 1 else 0 end) col
from tbl where data in ('X','Y')
union all
select 'B',sum(case when B='yes' then 1 else 0 end)
from tbl where data in ('X','Y')
union all
select 'C',sum(case when C='yes' then 1 else 0 end)
from tbl where data in ('X','Y')
union all
select 'D',sum(case when D='yes' then 1 else 0 end)
from tbl where data in ('X','Y')
union all
select 'E',sum(case when E='yes' then 1 else 0 end)
from tbl where data in ('X','Y')) tab
where col = 2;
Result:
colname
B
D
Related
I have question about mysql queries.
I have a table which have data below.
From To Weight
--------------
A B 1
A C 3
B C 2
D E 4
And I want to get sql result like below..
(?) A B C D E
----------------------
A 0 1 3 0 0
B 0 0 2 0 0
C 0 0 0 0 0
D 0 0 0 0 4
E 0 0 0 0 0
And what data is in original table is not determined.
How can I acheive this?
If you know the original columns, you can do:
select c.col1,
sum(case when to = 'A' then weight else 0 end) as a,
sum(case when to = 'B' then weight else 0 end) as b,
sum(case when to = 'C' then weight else 0 end) as c,
sum(case when to = 'D' then weight else 0 end) as d,
sum(case when to = 'E' then weight else 0 end) as d
from (select 'A' as col1 union all select 'B' union all select 'C' union all select 'D' union all select 'E'
) c left join
t
on t.from = c.col1
group by c.col1;
If you don't know the original columns, you could combine the values into a single string:
select col1.col,
group_concat(col2.col, ':', t.weight order by col2.col)
from ((select `from` as col from t
) union -- on purpose to remove duplicates
(select `to` from t
)
) col1 cross join
((select `from` as col from t
) union -- on purpose to remove duplicates
(select `to` from t
)
) col2 left join
t
on col1.col = t.`from` and col2.col = t.`from`
group by col1.col;
If you actually want separate columns and don't know the values, then you would need dynamic SQL.
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
Suppose I have a column which has three types of data like A, B, C. I want to group and count the number of each type.
For example if A is 3 times in column , B is 2 times and C is 1 time.
It should display as:
A B C
3 2 1
I would appreciate your help. Thankyou.
If you want the data in one row, you can use conditional aggregation:
select sum(col = 'a') as A, sum(col = 'b') as b, sum(col = 'c') as c
from t;
You can try the more explicit:
select sum(case when col = 'a' then 1 else 0 end) as A,
sum(case when col = 'b' then 1 else 0 end) as b,
sum(case when col = 'c' then 1 else 0 end) as c
from t;
I would actually suggest the following query:
SELECT
data, COUNT(*) AS cnt
FROM yourTable
GROUP BY data
This would generate counts in row form, e.g.
A 3
B 2
C 1
Most of the time this would meet your needs. If you instead really need columns you can try this:
SELECT
SUM(CASE WHEN data = 'A' THEN 1 ELSE 0 END) AS A,
SUM(CASE WHEN data = 'B' THEN 1 ELSE 0 END) AS B,
SUM(CASE WHEN data = 'C' THEN 1 ELSE 0 END) AS C
FROM yourTable
This would generate your literal expected output:
A B C
3 2 1
I have my table in this format
item A B C D
i1 4 0 2 0
i2 0 2 1 0
i3 2 0 0 2
i4 3 0 1 1
And, I'm looking for output where two columns are taken in combinations and if both elements value is >0 output value is taken as 1. And total count is calculated from all records
w1 w2 out
A B 0
A C 2
A D 2
B C 1
B D 0
C D 1
i,e for columns (A,C)>0 only i1 and i4 satisfy.So out=2
So far, I have solved this by querying for each item and then summing the value in php. Can this be possible entirely by sql query?
You can do it in SQL, but I think you still have to consider all the different combinations. Here is one approach using union all and conditional aggregation:
select col1name, col2name,
sum(col1 > 0 and col2 > 0)
from (select 'A' as col1name, 'B' as col2name, A as col1, B as col2
from t
union all
select 'A', 'C', A, C
from t
union all
select 'A', 'D', A, D
from t
union all
select 'B', 'C', B, C
from t
union all
select 'B', 'D', B, D
from t
union all
select 'C', 'D', C, D
from t
) t
EDIT:
There is another way, if you unpivot the data. This starts with this query:
select item, n.colname,
(case when n.colname = 'A' then A
when n.colname = 'B' then B
when n.colname = 'C' then C
else D
end) as colval
from t cross join
(select ';A' as colname union all select 'B' union all select 'C' union all select 'D'
);
We can now do a self join on the query to get all combinations and aggregate to get the results:
select col1.colname, col2.colname,
sum(col1.colval > 0 and col2.colval > 0)
from (select item, n.colname,
(case when n.colname = 'A' then A
when n.colname = 'B' then B
when n.colname = 'C' then C
else D
end) as colval
from t cross join
(select ';A' as colname union all select 'B' union all select 'C' union all select 'D'
)
) col1 join
(select item, n.colname,
(case when n.colname = 'A' then A
when n.colname = 'B' then B
when n.colname = 'C' then C
else D
end) as colval
from t cross join
(select ';A' as colname union all select 'B' union all select 'C' union all select 'D'
)
) col2
on col1.item = col2.item and
col1.colname < col2.colname
group by col1.colname, col2.colname;
This version is simpler if you have more than four columns. The number of combinations in the first methods will quickly become cumbersome.
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