I have a table generated from a query in TeraData that looks like this:
User_ID Transaction_Month Number_of_Visits
123 1 1
123 2 2
221 4 1
123 5 2
221 3 5
I am trying to create a Pivot table of sorts that will look like:
User_ID Month_1 Month_2 Month_3 Month_4 ..... Month_12
123
That will store the number of visits in each month column.
Any help would be greatly appreciated.
Thanks.
You can do conditional aggregation:
select user_id,
sum(case when transaction_month = 1 then number_of_visits else 0 end) month_1,
sum(case when transaction_month = 2 then number_of_visits else 0 end) month_2,
...
sum(case when transaction_month = 12 then number_of_visits else 0 end) month_12
from mytable
group by user_id
Related
I m having data in columns as:
item_id
month_in
amount
1
1
1500
1
1
1000
2
1
2500
3
1
2600
3
1
1000
4
1
2700
4
1
1000
1
2
1500
1
2
2000
2
2
1000
3
3
2500
3
3
2500
4
3
1000
4
3
2500
I want to have like this result
item_id
januari
februari
maret
1
2500
3500
0
2
2500
1000
0
3
3600
0
0
4
3700
0
3500
in oracle sql query how to solve this.
please help me
I have try this
select
item_id,
(case month_in=1 then sum(amout) end) AS januari
from table
group by item_id, month_in
order by item_id asc
but not working as I expected
We can try a pivot query here:
SELECT
item_id,
SUM(CASE WHEN month_in = 1 THEN amount ELSE 0 END) AS januari,
SUM(CASE WHEN month_in = 2 THEN amount ELSE 0 END) AS februari,
SUM(CASE WHEN month_in = 3 THEN amount ELSE 0 END) AS maret
FROM yourTable
GROUP BY
item_id
ORDER BY
item_id;
You almost got it. This is the simplest solution, without extra hassle:
SELECT
item_id,
SUM(CASE WHEN month_in = 1 THEN amount ELSE 0 END) AS januari,
SUM(CASE WHEN month_in = 2 THEN amount ELSE 0 END) AS februari,
SUM(CASE WHEN month_in = 3 THEN amount ELSE 0 END) AS maret
from table
group by item_id
order by item_id asc
You don't need to define the months as a separate rowset, because the months are defined as values 1, 2, 3, ... as columns. Similarly, the items are defined by the group by function.
The table that needs to be queried looks like this:
ID
UserID
ProductCodes
1
33
9999
2
456
3051
3
456
9999
4
456
3051
4
33
9999
How would I write a SQL query to find out which users have at least one productCodes = '9999' and also have more than 10 productCodes <> '9999'?
You can use GROUP BY and HAVING:
SELECT
UserID
FROM dbo.YourTable
GROUP BY
UserId
HAVING SUM(CASE WHEN ProductCodes = '9999' THEN 1 ELSE 0 END) >= 1
AND COUNT(DISTINCT ProductCodes) >= 11
;
Use Case or Intersect (case is more performant)
SELECT UserID, SUM (case when ProductCodes='9999' then 1 else 0 end) PC9999
, SUM (case when ProductCodes<>'9999' then 1 else 0 end) PCNot9999
FROM dbo.Users
WHERE ProductCodes='9999'
GROUP BY UserID
HAVING SUM (case when ProductCodes='9999' then 1 else 0 end)>0
AND SUM (case when ProductCodes<>'9999' then 1 else 0 end) >10
I ended up going with this. It allows us to get specific with how many times a '9999' product code has been used in comparison with other codes.
SELECT
UserID
FROM Session_Hst
GROUP BY
UserID
HAVING SUM(CASE WHEN ProductCodes = '9999' THEN 1 ELSE 0 END) >= 1
AND COUNT(CASE WHEN ProductCodes <> '9999' THEN 1 ELSE null END ) >= 10
;
Currently I have an orders table that is formatted with a row per month:
id
order_month
order_count
order_sum
111
2021-07
5
50
111
2021-08
10
50
111
2021-09
1
100
222
2021-07
8
80
222
2021-08
2
50
222
2021-09
1
80
Is there a way to format the SQL query so that the ouput has 1 row per id, and the other values are added as columns? E.g. something like:
id
2021-07_order_count
2021-07_order_sum
2021-08_order_count
2021-08_order_sum
2021-09_order_count
2021-09_order_sum
111
5
50
10
50
1
100
222
8
80
2
50
1
80
I think I am close with the following query:
SELECT
merchant_id,
(CASE WHEN order_month = '2021-07' THEN order_count ELSE 0 END) as '2021-07-orderCount',
(CASE WHEN order_month = '2021-07' THEN order_sum ELSE 0 END) as '2021-07-orderSum',
(CASE WHEN order_month = '2021-08' THEN order_count ELSE 0 END) as '2021-08-orderCount',
(CASE WHEN order_month = '2021-08' THEN order_sum ELSE 0 END) as '2021-08-orderSum',
(CASE WHEN order_month = '2021-09' THEN order_count ELSE 0 END) as '2021-09-orderCount',
(CASE WHEN order_month = '2021-09' THEN order_sum ELSE 0 END) as '2021-09-orderSum'
FROM orders
ORDER BY id
It is creating a separate column and putting the correct values in each column.
However when I try and group by Id it then only shows the first result:
Thank you.
You need conditional aggregation:
SELECT id,
MAX(CASE WHEN order_month = '2021-07' THEN order_count ELSE 0 END) `2021-07-orderCount`,
MAX(CASE WHEN order_month = '2021-07' THEN order_sum ELSE 0 END) `2021-07-orderSum`,
MAX(CASE WHEN order_month = '2021-08' THEN order_count ELSE 0 END) `2021-08-orderCount`,
MAX(CASE WHEN order_month = '2021-08' THEN order_sum ELSE 0 END) `2021-08-orderSum`,
MAX(CASE WHEN order_month = '2021-09' THEN order_count ELSE 0 END) `2021-09-orderCount`,
MAX(CASE WHEN order_month = '2021-09' THEN order_sum ELSE 0 END) `2021-09-orderSum`
FROM orders
GROUP BY id
ORDER BY id;
See the demo.
I have a table which stores purchase info from sellers and table contains rating to every purchase out of 5 stars. I want to have output Group By sellers and Each sellers good(Above 3) and bad(Below 4) ratings count
PurchaseId SellerId PurchaseRating
1 ABC 2
2 ABC 5
3 DEF 1
4 XYZ 2
5 DEF 4
7 ABC 3
OUTPUT
SellerId TotalOrders AvgRating Above3*(4&5) Below4*(1 to 3)
ABC 3 3.3 1 2
DEF 2 2.5 1 1
XYZ 1 2 0 1
For first 3 columns I am getting result using this
Select SellerId, Count(P.Id) TotalOrders, Avg(PurchaseRating) AvgRating,
CASE WHEN P.PurchaseRating >= 4 THEN 1 ELSE 0 END AS Above3*(4&5)
from
[dbo].[AmazonAbeOrdersPurchaseInfo] P
Where PurchaseRating is not null
Group by P.SellerId
order by TotalOrders desc
Unable to identify how to include case in group by clause.
You are trying to do conditional aggreation. The important thing is that you want the conditional expression inside the aggregate function:
select
sellerId,
count(*) totalOrders,
avg(purchaseRating) avgRating,
sum(case when purchaseRating > 3 then 1 else 0 end) above3,
sum(case when purchaseRating < 4 then 1 else 0 end) below4
from [dbo].[AmazonAbeOrdersPurchaseInfo]
where purchaseRating is not null
group by sellerId
order by totalOrders desc
I need to write query on employee table to fetch the employee with employee ID & how many days he is present absent & half-day for given date range.
Employee
AID EmpID Status Date
1 10 Present 17-03-2015
2 10 Absent 18-03-2015
3 10 HalfDay 19-03-2015
4 10 Present 20-03-2015
5 11 Present 21-03-2015
6 11 Absent 22-03-2015
7 11 HalfDay 23-03-2015
Expected Output will be :
EmpID Present Absent HalfDay
10 2 1 1
11 1 1 1
Can you please help me with the Sql query ?
Here Is the query I tried
SELECT EMP.EMPID,
(CASE WHEN EMP.STATUS = 'Present' THEN COUNT(STATUS) ELSE 0 END) Pres,
(CASE WHEN EMP.STATUS = 'Absent' THEN COUNT(STATUS) ELSE 0 END) ABSENT,
(CASE WHEN emp.status = 'HalfDay' THEN Count(status) ELSE 0 END) HalfDay
FROM EMPLOYEE EMP GROUP BY emp.empid
The COUNT() function tests if the value is NOT NULL. Therefore it will always increment for both sides of a CASE statement like this:
COUNT(CASE Status WHEN 'Present' THEN 1 ELSE 0) AS Present
So we need to use SUM() ...
select empid,
sum(case when status='Present' then 1 else 0 end) present_tot,
sum(case when status='Absent' then 1 else 0 end) absent_tot,
sum(case when status='HalfDay' then 1 else 0 end) halfday_tot
from employee
group by empid
order by empid
/
... or use COUNT() with a NULL else clause. Both produce the same output, perhaps this one is clearer:
SQL> select empid,
2 count(case when status='Present' then 1 end) present_tot,
3 count(case when status='Absent' then 1 end) absent_tot,
4 count(case when status='HalfDay' then 1 end) halfday_tot
5 from employee
6 group by empid
7 order by empid
8 /
EMPID PRESENT_TOT ABSENT_TOT HALFDAY_TOT
---------- ----------- ---------- -----------
10 2 1 1
11 1 1 1
SQL>
Note that we need to use ORDER BY to guarantee the order of the result set. Oracle introduced a hashing optimization for aggregations in 10g which meant GROUP BY rarely returns a predictable sort order.
Replace 0 with null because it would be also come in count and added the where clause for date range, check the example below:
select empID,
count(case when status='Present' then 1 else null end) Present_Days,
count(case when status='Absent' then 1 else null end) Absent_Days,
count(case when status='HalfDay' then 1 else null end) HalfDays
from Employee
where date >= to_date('17mar2015') and date <= to_date('23mar2015')
group by empID