Sum with multiple conditions and GROUP BY - sql

I have these 3 tables :
order_details
id
date
5
15/12/2022
6
15/12/2022
7
16/12/2022
order_items
id
orderId
productId
quantity
7
5
5
10
8
5
6
5
9
5
7
2
10
6
5
10
11
6
6
5
12
6
7
2
13
7
5
7
14
7
6
3
products
id
name
5
productOne
6
productTwo
7
productThree
I want to join these 3 tables and have a list of products associated with their date and sum of the quantities
For example for these tables I want this:
date
product_name
quantity
15/12/2022
productOne
20
15/12/2022
productTwo
10
15/12/2022
productThree
4
15/12/2022
productOne
20
15/12/2022
productTwo
10
15/12/2022
productThree
4
16/12/2022
productOne
7
16/12/2022
productTwo
3
If someone can help me it would be so beautiful...
Here is my work on my side ->
SELECT *
FROM order_details
JOIN (SELECT order_items.orderId,
order_items.productId,
order_items.quantity,
products.name,
SUM(order_items.quantity)
FROM order_items
INNER JOIN products
ON order_items.productId = products.id
GROUP BY order_items.productId) AS items
GROUP BY order_details.date, items.productId

Related

Create a Final Group of items if at least one Intermediate Group in common exists between two items

After to have group the item based on first criteria we obtain this result.
My_table (reference in the SQL script below)
item
group
1,6
1
2
2
3,5
3
4,5
4
6
5
7,10,11
6
8,10,11,13
7
9
8
12,15,18
9
14
10
14,15,18,20
11
21
2
This group is an intermediate group.
So, to find the final group, we explode the intermediate group to see what are all the groups to which an element belongs.
And the output intermediate is
item
group
1
1
2
2
3
3
4
4
5
3
5
4
...
...
10
6
10
7
11
6
11
7
12
9
13
7
...
...
18
11
20
11
21
2
we have as many lines for an item as it has groups
Below, we must aggregate the item 1 and 6 because they have at least one group in common, the group 1. Then we aggregate item 3, 4, 5 because there have at least one group in common. Same for item 7,8,10,11 and 13. The same again for 14,15,16 and 20. Only item 9 has not common group with each other.
So the second output intermediate expected is to put for each item all its groups like this.
item
group
1
1
2
2
3
3
4
4
5
3,4
6
1
6
5
7
6
8
7
9
8
10
6,7
11
6,7
12
9
13
7
14
10,11
15
9,11
18
9,11
20
11
21
2
this will allow us to create a new group in which we will have the items that have similar intermediate groups. This is the expected result
item
inter_group
final_group
1
1
1
2
2
2
3
3
3
4
3,4
3
5
3,4
3
6
1,5
1
7
6,7
7
8
6,7
7
9
8
9
10
6,7
7
11
6,7
7
12
9,10,11
8
13
6,7
7
14
9,10,11
8
15
9,10,11
8
18
9,10,11
8
20
9,10,11
8
21
2
2
Actually, the final group is correct when each item has unique group and that there is no more possible crossing with other groups.
So i've try a recursive function in SQL but it stop at the first step (inter group) :
WITH RECURSIVE
T1 AS (
SELECT
item,
intermediate_group,
FROM my_table, unnest(split(group)) AS item)
,
T2 as (
SELECT item,
STRING_AGG(CAST(intermediate_group as STRING)) AS intermediate_group
from T1
GROUP BY item)
SELECT DISTINCT item, intermediate_group as final_group
FROM T2
Thanks for your help
Consider below
select *, dense_rank() over(order by inter_group) as final_group
from (
select item,
string_agg('' || `group`) as inter_group
from your_table, unnest(split(item)) item
group by item
)
# order by final_group
if applied to sample data in your question - output is

counter on SQL SELECT statement based on the values of the current line

I have the following SQL table (first table) where this table stores the orders of a specific shop. I am not sure if it's possible but I want to produce a view like the second table.
The field orderNumber hold the number of a specific order. The lines that have the same order number means that belongs to the same order.
So based on the orderNumber and the type of the first table I want to produce the field dealCounter (see second table) where counts the numbers of deals of each order and assigns the same number of dealCounter to all the lines tha belongs to the same order.
Each time we find type 12 then we increase the dealCounter by one. If we change the orderNumber then reset the dealCounter.
I have tried to use the rank() function but I couldn't manage the dealCounter and set the values that I want.
Does any way which can solve my problem?
menuid type orderNumber storeNumber lineNumber
---------------------------------------------------
10 12 100122 10 0
8 9 100122 10 1
5 9 100122 10 2
3 9 100122 10 3
11 12 100122 10 4
5 9 100122 10 5
3 9 100122 10 6
10 12 100122 10 7
8 9 100122 10 8
5 9 100122 10 9
3 9 100122 10 10
10 12 100123 10 0
8 9 100123 10 1
5 9 100123 10 2
3 9 100123 10 3
11 12 100123 10 4
5 9 100123 10 5
3 9 100123 10 6
dealCounter menuid type orderNumber storeNumber lineNumber
---------------------------------------------------------------
1 10 12 100122 10 0
1 8 9 100122 10 1
1 5 9 100122 10 2
1 3 9 100122 10 3
2 11 12 100122 10 4
2 5 9 100122 10 5
2 3 9 100122 10 6
3 10 12 100122 10 7
3 8 9 100122 10 8
3 5 9 100122 10 9
3 3 9 100122 10 10
1 10 12 100123 10 0
1 8 9 100123 10 1
1 5 9 100123 10 2
1 3 9 100123 10 3
2 11 12 100123 10 4
2 5 9 100123 10 5
2 3 9 100123 10 6
You can use CROSS APPLY:
SELECT t3.cnt AS dealCounter, menuid, type, orderNumber, storeNumber
FROM mytable AS t1
CROSS APPLY (
SELECT COUNT(CASE WHEN type = 12 THEN 1 END) AS cnt
FROM mytable AS t2
WHERE t1.orderNumber = t2.orderNumber
AND t2.lineNumber <= t1.lineNumber) AS t3
For every row of mytable we apply CROSS APPLY operator, so as to get the count of type=12 records that precede or coincide with the row and fall within the same orderNumber slice.
Demo here
select
sum(case when type=12 then 1 end)
over (partition by ordernumber order by lineNumber) as dealCounter,
menuid, type, orderNumber, storeNumber
from your_table;
This is a running sum(we are ordering by lineNumber) considering a 1 where type=12. The counter will reset at every new orderNumber(partition by)
Edit: Used Giorgios's fiddle. Despite of your version which commenters say does not support running sum, this seems to run ok on sqlfiddle.
Result.

summarising a 3 months sales report across 2 branches into top 3 product for each month

I have the following REPORT table
m = month,
pid = product_id,
bid = branch_id,
s = sales
m pid bid s
--------------------------
1 1 1 20
1 3 1 11
1 2 1 14
1 4 1 16
1 5 1 31
1 1 2 30
1 3 2 10
1 2 2 24
1 4 2 17
1 5 2 41
2 3 1 43
2 5 1 21
2 4 1 10
2 1 1 5
2 2 1 12
2 3 2 22
2 5 2 10
2 4 2 5
2 1 2 4
2 2 2 10
3 3 1 21
3 5 1 10
3 4 1 44
3 1 1 4
3 2 1 14
3 3 2 10
3 5 2 5
3 4 2 6
3 1 2 7
3 2 2 10
I'd like to have a summary of this sales table
by showing the top 3 sales among the products across all branches.
something like this:
m pid total
---------------------
1 5 72
1 1 50
1 4 33
2 3 65
2 5 31
2 2 22
3 4 50
3 3 31
3 2 24
so on month 1, product #5 has the highest total sales with 72, followed by product #1 is 50.. and so on. if i could separate them into different table for each month would be better
so far what i can do is make a summary for 1 month and shows the entire thing and not top 3.
select pid, sum(s)
from report
where m = 1
group by pid
order by sum(s);
thanks a lot!
Most databases support the ANSI standard window functions. You can do what you want with row_number():
select m, pid, s
from (select r.m, r.pid, sum(s) as s,
row_number() over (partition by m order by sum(s) desc) as seqnum
from report r
group by r.m, r.pid
) r
where seqnum <= 3
order by m, s desc;

SQL(Oracle) select the most common value (multiple tables)

I want to know which seat was the most sold by individual halls?
TICKETS
IDTICKET MOVIE_IDMOVIE HALL_IDHALL PRICE SEAT ROW
1 10 2 4 10 6
2 5 2 4 10 5
3 5 2 4 10 4
4 8 5 4 3 1
5 7 5 4 4 15
6 10 7 4 7 9
7 6 2 4 14 3
HALLS
IDHALL PLACE_IDPLACE NAME NUMSEATS EQUIPMENT
1 5 A1 250 high
2 5 B1 200 medium
3 5 B2 200 medium
4 5 C2 180 medium
5 5 C2 180 medium
6 9 old hall 120 low
Display should look like
B1 10
C2 3
...
SELECT b.Name, a.Seat
FROM (SELECT Hall, Seat, COUNT(1) AS SeatCount, RANK() OVER (PARTITION BY Hall ORDER BY COUNT(1) DESC) AS SeatRank
FROM SEAT
GROUP BY Hall, Seat ) a
INNER JOIN
HALL b
ON a.HALL_IDHALL = b.IDHALL
WHERE a.SeatRank = 1
select h.name,t.hall_idhall,h.idhall, max(t.seat) from tickets t, hall h where t.hall_idhall=h.idhall
group by h.name,t.hall_idhall,h.idhall
Try the above query

mysql count from same table and data from the other table

I want to display the name of the registered users with the count of regid by supplying replyid, I don't know what will be the correct query to get the results
Here are the tables.
details_table
id regid replyid
-------------------
1 1 2
2 1 3
6 2 4
5 3 4
8 2 5
9 3 5
10 4 5
11 5 5
12 2 6
13 6 6
14 4 6
15 7 7
16 8 7
17 9 7
18 10 8
19 2 9
20 2 10
21 11 10
22 12 10
reg_table
id regname
---------------
1 Sam
2 Ash
3 Tina
4 Rohny
5 Martin
6 Natasha
7 Natalia
8 Kim
9 Alex
10 John
11 Neil
12 Peter
So if replyid i.e. (10) is select from details_table by where clause, it's suppose to display the 2,11,12 i.e. (Ash,Neil,Peter) from reg_table with the count of Ash=5,Neil=1,Peter=1
SELECT a.id, a.regname, COUNT(1)
FROM reg_table a, details_table b,
details_table c
WHERE b.replyid=10
AND b.regid = a.id
AND c.regid = a.id
GROUP BY a.id, a.regname
SELECT r.regid, r.regname, count(*)
FROM (
SELECT DISTINCT regid
FROM details_table
WHERE replyid = 10
) rg
JOIN reg_table r ON rg.regid = r.regid
JOIN details_table d ON r.regid = d.regid
GROUP BY r.regid
try this
select count(dt.regid) as cnt, regname from details_table dt, reg_table rt where dt.regid = rt.Regid and dt.replyid = 10 group by rt.Regid
SELECT reg_table.regname, count(*) from reg_table, details_table where details_table.regid = reg_table.id GROUP BY reg_table.id