I created the MariaDB(10.1.21) table named 'group_test' and saved some data as below.
Group Item Value1 Value2 Value3
A a1 1 0 0
A a2 1 1 1
A a3 1 1 2
B b1 1 1 0
B b2 1 1 1
B b3 1 0 0
B b4 1 1 3
C c1 1 1 0
C c2 1 1 1
Using a query, I want to make the result as below at once.
Group Items Value1_1 Value2_1 Value3_1
A 3 3 2 1
B 4 4 3 1
C 2 2 2 1
Items means the total number of 'Item' in the 'Group'.
ValueN_1 means the total number of 'ValueN' value equal to 1 in the 'Group'.
I think I would use GROUP BY and COUNT but I don't know exactly what to do.
How do I write SQL to get the above results in one query?
Thanks.
Simply do a GROUP BY. Since Value1 to Value3 are only 0's and 1's, you can use SUM() to count the 1's.
select Group, count(Item), sum(Value1), sum(Value2), sum(Value3)
from tablename
group by Group
Edit: "ValueN can have a value from 0 to 4":
select Group,
count(Item),
sum(case when Value1 = 1 then 1 else 0 end) Value1_1,
sum(case when Value2 = 1 then 1 else 0 end) Value2_1,
sum(case when Value3 = 1 then 1 else 0 end) Value3_1
from tablename
group by Group
Assuming value1, value2 and value3 can only be either 0 or 1, you can write it like this
select Group,
count(*) as Items,
sum(value1) as Value1_1,
sum(value2) as Value2_1,
sum(value3) as Value3_1
from yourTable t1
group by Group
If that's not the case, you will have to use a case in the sum
select Group,
count(*) as Items,
sum(case when value1 = 1 then 1 else 0 end) as Value1_1,
sum(case when value2 = 1 then 1 else 0 end) as Value2_1,
sum(case when value3 = 1 then 1 else 0 end) as Value3_1
from yourTable t1
group by Group
Use GROUP BY clause and SUM aggregate function in SELECT statement
SELECT *
FROM
(
SELECT [Group], count(Item) Item, sum(Value1) Value1, sum(Value2) Value2,
sum(Value3) Value3
FROM Your_tableName
GROUP BY [Group]
) A
Related
i have following table
id statusid
100 1
100 2
100 3
101 1
101 3
i am getting the result like following
id data1 data2 data3
100 1 1 1
101 1 0 1
but i want the result like following
id data1 data2+data3
100 1 2
101 1 1
i am using the following query:
select id, SUM(CASE WHEN statusid=1 THEN 1 ELSE 0 END) AS data1,
SUM(CASE WHEN statusid=2 THEN 1 ELSE 0 END) AS data2,
SUM(CASE WHEN statusid=3 THEN 1 ELSE 0 END) AS data3
from employee
group by id
any help.
thank you.
Sudha.
You can count statuses 2 and 3 together like so:
select id,
sum(case when statusid = 1 then 1 else 0 end) as data1,
sum(case when statusid in (2, 3) then 1 else 0 end) as data2_3
from employee
group by id
You may use PIVOT clause to get the required result.
Use DECODE to map the status so that the 2 and 3 produce the same value
with tab2 as (select
id, decode(status_id,3,2,status_id) status_id2
from tab)
select * from tab2
PIVOT (count(*) "CNT" for status_id2 in
(1 as "DATA_1",
2 as "DATA_2_3")
)
ID DATA_1_CNT DATA_2_3_CNT
---------- ---------- ------------
100 1 2
101 1 1
I have a Table like so:
ID1|ID2|ID3|Enabled
1 1 0 1
1 1 1 1
1 1 2 1
2 1 1 1
2 1 2 1
2 1 3 1
3 1 0 0
3 1 1 1
3 1 2 1
4 1 0 1
4 1 0 1
4 1 0 1
I want to group by first ID1 then ID2 and select all ID1 where within each group, ID3 contains both 0 (If Enabled column is 1) and nonzero value. So the table provided will return -
ID1
1
SELECT ID1 From Table1
GROUP BY ID1, ID2
WHERE
???
You want a having clause, if your definition of group is based on ID1/ID2:
SELECT ID1, ID2
FROM Table1
GROUP BY ID1, ID2
HAVING SUM(CASE WHEN ID3 = 0 AND Enabled = 1 THEN 1 ELSE 0 END) > 0 AND
SUM(CASE WHEN ID3 <> 0 THEN 1 ELSE 0 END) > 0;
You need a group by with an alternative having as you would not be able to use having for id3 as id3 should be present in group by first to be used in having else ypu can use only aggregates in having. So, In order to make the id3 case work I have used here case when which is checking id3 if found as either 0 or 1 would be returning value as 1 in each such case. Therefore, the sum on top of case act as an aggregate in having hence would work as if sum obtained based on the cases comes as greater than or equal to 2 or more(if duplicates of 0 and 1) then output those rows of that partcular group.
select ID1
from Table1
where enabled = 1
group by ID1, ID2
having sum( case when ID3 in (1,0) then
1 else 0 end) >= 2
I have table like this
id col1 col2
1 A 1
2 B 0
3 A 1
4 C 1
5 B 0
6 A 0
7 C 1
8 C 1
9 B 1
10 B 0
I need a query something like this
Values 1 0
A 2 1
B 1 3
C 3 0
In the above result the header shows the col2 distinct values (1,0) and rows names represents distinct values of col1. The values in the table shows the counts.
Any suggestion to get the result like this in postgresql?
You need conditional aggregation :
select col1,
sum(case when col2 = 1 then 1 else 0 end) as 1,
sum(case when col2 = 0 then 1 else 0 end) as 0
from table t
group by col1;
You could also use FILTER:
SELECT
col1,
COUNT(*) FILTER (WHERE col2 = 1) AS 1,
COUNT(*) FILTER (WHERE col2 = 0) AS 0,
FROM
foo
GROUP BY
col1;
Here are simpler ways to write this logic. The first is Postgres-specific:
select col1,
sum( (col2 = 1)::int ) as num_1,
sum( (col2 = 0)::int as num_0
from t
group by col1;
The second just uses arithmetic:
select col1,
sum( col2 ) as num_1,
sum( 1 - col2 ) as num_0
from t
group by col1;
Trying to get the count of distinct people in the intersection of top two circles. (In the figure I am trying to get the count for the region labeled as d). Keys 1,2 and 3 belong to first circle and 4,5,6 belong to second circle and 7,8,9,10 belong to third circle.
Table structure is as follows:
customer key
A234 1
A345 4
A12 5
A989 6
This is the query I have tried:
select count(distinct(c.key))
from (select c.key
from tab1 c
group by c.key
having sum(case when key1 in (1,2,3) then 1 else 0 end) > 0 and
sum(case when key1 in (4,5,6,7,8) then 1 else 0 end) = 0
) c
I think you simply got your HAVING clause mixed up.
select count(*)
from
(
select key
from tab1
group by key
having sum(case when key1 in (1,2,3) then 1 else 0 end) > 0 -- in circle A
and sum(case when key1 in (4,5,6) then 1 else 0 end) > 0 -- in circle B
and sum(case when key1 in (7,8,9,10) then 1 else 0 end) = 0 -- not in circle C
) region_d;
I'm trying to do a full join on two SQL queries, below:
1st Query:
SELECT
ID
,SUM(CASE WHEN reason = 4 THEN 0 ELSE quantity*price END) AS TValue
,COUNT(*) AS CountAll
FROM table1
WHERE Date>=#StartDate AND Date<=#EndDate
GROUP BY ID
2nd Query:
SELECT
ID
,SUM(CASE WHEN reason = 1 THEN 1 ELSE 0 END) AS New
,SUM(CASE WHEN reason = 6 THEN 1 ELSE 0 END) AS Amend
,SUM(CASE WHEN reason = 5 THEN 1 ELSE 0 END) AS Cancel
FROM Table2
WHERE Date2 >=#StartDate AND Date2<= #EndDate
GROUP BY ID
Result from query1
ID CountAll TValue
-------------------------
id1 24 1020
id2 13 2030
id3 4 120
Result from query 2:
ID New Amend Cancel
--------------------------------
id1 12 4 6
id2 7 6 1
id4 2 1 2
Needed output:
ID TValue CountAll New Amend Cancel Total(countall+new+amend+cancel)
----------------------------------------------------------------------------------------
Id1 1020 24 12 4 6 46
Id2 2030 13 7 6 1 27
id3 120 4 0 0 0 4
Id4 0 0 2 1 2 5
I'll post my current solution if requested, but it is pretty far from working.
I've been doing a bit of research and I think I need to either make a union to join the ID'S, or just do a Full Join. (Second day ever doing sql)
Try this,
SELECT *
FROM
(
SELECT ID ,
SUM(CASE WHEN reason = 4 THEN 0 ELSE quantity*price END) AS TValue,
COUNT(*) AS CountAll
FROM table1
WHERE Date>=#StartDate AND Date<=#EndDate
GROUP BY ID
) a FULL JOIN
(
SELECT ID ,
SUM(CASE WHEN reason = 1 THEN 1 ELSE 0 END) AS New ,
SUM(CASE WHEN reason = 6 THEN 1 ELSE 0 END) AS Amend ,
SUM(CASE WHEN reason = 5 THEN 1 ELSE 0 END) AS Cancel
FROM Table2
WHERE Date2 >=#StartDate AND Date2<= #EndDate
GROUP BY ID
) b ON a.ID = b.ID
I would write something like below:
select decode (a.id, null, b.id, a.id) as ID, a.TValue, CountAll, b.new, b.Amend, b.cancel
from (SELECT ID ,SUM(CASE WHEN reason = 4 THEN 0 ELSE quantity*price END)
AS TValue ,COUNT(*) AS CountAll
FROM table1
WHERE Date>=#StartDate AND Date<=#EndDate GROUP BY ID
) a FULL OUTER JOIN
(SELECT ID , SUM(CASE WHEN reason = 1 THEN 1 ELSE 0 END)
AS New ,SUM(CASE WHEN reason = 6
THEN 1 ELSE 0 END) AS Amend ,
SUM(CASE WHEN reason = 5 THEN 1 ELSE 0 END) AS Cancel
FROM Table2 WHERE Date2 >=#StartDate AND Date2<= #EndDate GROUP BY ID
) b
on a.id = b.id
have you tried this...
select isnull (a.id,b.id) as ID, a.TValue, CountAll, b.new, b.Amend, b.cancel
from (SELECT ID ,SUM(CASE WHEN reason = 4 THEN 0 ELSE quantity*price END) AS TValue ,COUNT(*) AS CountAll
FROM table1
WHERE Date>=#StartDate AND Date<=#EndDate GROUP BY ID ) a
FULL OUTER JOIN (SELECT ID , SUM(CASE WHEN reason = 1 THEN 1 ELSE 0 END) AS New ,SUM(CASE WHEN reason = 6 THEN 1 ELSE 0 END) AS Amend , SUM(CASE WHEN reason = 5 THEN 1 ELSE 0 END) AS Cancel
FROM Table2 WHERE Date2 >=#StartDate AND Date2<= #EndDate GROUP BY ID ) b on a.id = b.id