sum values grouping sets of columns in postgresql 9.6 - sql

CREATE TABLE products(
id integer,
country_id integer,
category_id smallint,
product_count integer
);
INSERT INTO products VALUES
(1,12,1,2),
(2,12,1, 4),
(3,12,2,1),
(4,45,5,2),
(5,45,5,1),
(6,45,8,5),
(7,3,1,3),
(8,3,1,3)
-----------------------------------------------------
id | country_id | category_id | product_count
-----------------------------------------------------
1 12 1 2
2 12 1 4
3 12 2 1
4 45 5 2
5 45 5 1
6 45 8 5
7 3 1 3
8 3 1 3
What i want to see is like that, I want to sum product_counts by grouping category_id under every grouped country_id;
---------------------------------------------------------------------
id | country_id | category_id | product_count | total_count
---------------------------------------------------------------------
1 12 1 2 6
2 12 1 4 6
3 12 2 1 1
4 45 5 2 3
5 45 5 1 3
6 45 8 5 5
7 3 1 3 6
8 3 1 3 6
I tried this, but it didn't help. This doesn't make the trick and bring summed value of product_count for each grouped category_id;
SELECT *,SUM(r.product_count) as sum FROM (
SELECT id,
country_id,
category_id,
product_count
FROM products
) r
GROUP BY r.country_id,r.category_id,r.product_count, r.id
ORDER BY r.country_id , r.category_id, r.product_count;

I grouped by both country_id,category_id to get requested result:
et=# select *,sum(product_count) over (partition by country_id,category_id) from products order by id;
id | country_id | category_id | product_count | sum
----+------------+-------------+---------------+-----
1 | 12 | 1 | 2 | 6
2 | 12 | 1 | 4 | 6
3 | 12 | 2 | 1 | 1
4 | 45 | 5 | 2 | 3
5 | 45 | 5 | 1 | 3
6 | 45 | 8 | 5 | 5
7 | 3 | 1 | 3 | 6
8 | 3 | 1 | 3 | 6
(8 rows)

Related

SQL : Get the 3 first occurrences of a field

I have a PostgreSQL table with 2 fields like the following. Field A is the primary key.
A | B
------
1 | 1
2 | 1
3 | 1
4 | 1
5 | 2
6 | 2
7 | 2
8 | 2
9 | 2
10 | 3
11 | 3
I'm looking for a request to get only the 3 first occurrences of B, like this:
A | B
1 | 1
2 | 1
3 | 1
5 | 2
6 | 2
7 | 2
10 | 3
11 | 3
Does somebody have a solution?
You want row_number() :
select t.*
from (select t.*, row_number() over (partition by b order by a) as seq
from table t
) t
where seq <= 3;

I have a SQL table which is like tree structure, I want to group it & count for depth 2

I have managed to group child group, now in that same, I want to some header count based on all child in that table
Head child assigned total
In In1 3 5
In In2 2 3
In In3 2 3
In In4 1 3
In In5 0 4
In In6 4 4
In In7 3 7
In In8 2 3
Ma Ma1 2 5
Ma Ma2 0 5
Usr us1 4 4
Usr us2 1 3
So, I copied child's assigned, total column.
Head assigned total child assigned total
In 3 5 In1 3 5
In 2 3 In2 2 3
In 2 3 In3 2 3
In 1 3 In4 1 3
In 0 4 In5 0 4
In 4 4 In6 4 4
In 3 7 In7 3 7
In 2 3 In8 2 3
Ma 2 5 Ma1 2 5
Ma 0 5 Ma2 0 5
Us 4 4 us1 4 4
Us 1 3 us2 1 3
Now I want to group parent 1, So, all count of In (In1 - In8) should be sum and be in header assignedHead, totalHead
Head assigned total child assigned total
In 17 32 In1 3 5
In 17 32 In2 2 3
In 17 32 In3 2 3
In 17 32 In4 1 3
In 17 32 In5 0 4
In 17 32 In6 4 4
In 17 32 In 3 7
In 17 32 In8 2 3
Ma 2 10 Ma1 2 5
Ma 2 10 Ma2 0 5
Us 5 7 us1 4 4
Us 5 7 us2 1 3
Or something like this which is efficient.
You can do a window sum (if your RDBMS supports window functions):
select
head,
assigned,
total,
sum(assigned) over(partition by head) sum_assigned,
sum(total) over(partition by head) sum_total
from mytable
Demo on DB Fiddle:
head | assigned | total | sum_assigned | sum_total
:--- | -------: | ----: | -----------: | --------:
In | 3 | 5 | 17 | 32
In | 2 | 3 | 17 | 32
In | 2 | 3 | 17 | 32
In | 1 | 3 | 17 | 32
In | 0 | 4 | 17 | 32
In | 4 | 4 | 17 | 32
In | 3 | 7 | 17 | 32
In | 2 | 3 | 17 | 32
Ma | 2 | 5 | 2 | 10
Ma | 0 | 5 | 2 | 10
Usr | 4 | 4 | 5 | 7
Usr | 1 | 3 | 5 | 7

How can I get the matrix for these tables?

I have two tables here and need to produce a matrix for all combinations
Table 1
Brand Company ID
1 1 1
2 2 2
3 3 3
Table 2
Prod1 Prod2 Prod3 Prod4 Prod5
4 5 6 18 19
5 6 7 20 5
The result I'm trying to achieve
Result table:
Brand Company ID Prod1 Prod2 Prod3 Prod4 Prod5
1 1 1 4 5 6 18 19
1 1 1 5 6 7 20 5
2 2 2 4 5 6 18 19
2 2 2 5 6 7 20 5
I could have worked with this if they have some kind of ID just not to how to approach this to get the matrix.
Thank you
Not sure what happened to the third row from table1 in your query and why it isn't in the result, but I think you are looking for a cross join.
select Brand, Company, ID, Prod1, Prod2, Prod3, Prod4, Prod5
from table1
cross join table2
rextester demo: http://rextester.com/UOZ33372
returns (with added order by):
+-------+---------+----+-------+-------+-------+-------+-------+
| Brand | Company | ID | Prod1 | Prod2 | Prod3 | Prod4 | Prod5 |
+-------+---------+----+-------+-------+-------+-------+-------+
| 1 | 1 | 1 | 4 | 5 | 6 | 18 | 19 |
| 1 | 1 | 1 | 5 | 6 | 7 | 20 | 5 |
| 2 | 2 | 2 | 4 | 5 | 6 | 18 | 19 |
| 2 | 2 | 2 | 5 | 6 | 7 | 20 | 5 |
| 3 | 3 | 3 | 4 | 5 | 6 | 18 | 19 |
| 3 | 3 | 3 | 5 | 6 | 7 | 20 | 5 |
+-------+---------+----+-------+-------+-------+-------+-------+

Delete rows with repeat column values

I have a table that looks like this:
ID VAR1 VAR2 VAR3 VAR4 VAR5 VAR6 VAR7 VAR8 VAR9 VAR10
1 2 1 3 5 2 1 3 5 3 1
2 1 1 1 1 1 1 1 1 1 1
3 1 3 4 7 2 4 1 3 4 6
4 2 2 2 2 2 2 2 2 2 2
5 1 3 5 6 7 4 6 7 4 6
6 3 3 3 3 3 3 3 3 3 3
How do I delete rows (in this case ID # 2,4,6) which have non-distinct values, i.e. the same number in every column, (1,1,1,1,1)?
How about...
DELETE FROM tablename WHERE
VAR1=VAR2
AND VAR2=VAR3
AND VAR3=VAR4
AND VAR4=VAR5
AND VAR5=VAR6
AND VAR6=VAR7
AND VAR7=VAR8
AND VAR8=VAR9
AND VAR9=VAR10
Hopefully you'll need to run this only once - I imagine most of the vars will not be indexed so you'll might end up locking the table or this delete. It would be better to prevent these rows from being inserted I guess.
in SQL Server; using cross apply(values ...) to unpivot the columns along then aggregate and filter with count(distinct ...)=1:
delete t
where id in (
select t.id
from t
cross apply (values (VAR1),(VAR2),(VAR3),(VAR4),(VAR5),(VAR6),(VAR7),(VAR8),(VAR9),(VAR10)
) u(Var)
group by t.id
having count(distinct u.var)=1
)
rextester demo: http://rextester.com/WZE91559
returns:
+----+------+------+------+------+------+------+------+------+------+-------+
| ID | VAR1 | VAR2 | VAR3 | VAR4 | VAR5 | VAR6 | VAR7 | VAR8 | VAR9 | VAR10 |
+----+------+------+------+------+------+------+------+------+------+-------+
| 1 | 2 | 1 | 3 | 5 | 2 | 1 | 3 | 5 | 3 | 1 |
| 3 | 1 | 3 | 4 | 7 | 2 | 4 | 1 | 3 | 4 | 6 |
| 5 | 1 | 3 | 5 | 6 | 7 | 4 | 6 | 7 | 4 | 6 |
+----+------+------+------+------+------+------+------+------+------+-------+

Summary of row values according to summation of n number

I have table like this
a | b
_____
1 | 1
2 | 2
3 | 3
4 | 4
5 | 5
and i want the result like this
a | b | c
_________
1 | 1 | 1
2 | 2 | 3
3 | 3 | 6
4 | 4 | 10
5 | 5 | 15