Delete rows with repeat column values - sql

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 |
+----+------+------+------+------+------+------+------+------+------+-------+

Related

Generating Duplicate Data Series

This example I am trying to generate and add column 1 to 5 as many number as I want. Can I solve with "Connect By" function or another function?
SELECT level
FROM dual
CONNECT BY level <=5;
ID Name Expected Outcome
----- ---- ---------------
1 | A | 1
2 | B | 2
3 | C | 3
4 | D | 4
5 | E | 5
6 | F | 1
7 | G | 2
8 | G | 3
9 | A | 4
10 | E | 5
11 | E | 1
12 | E | 2
Use the MOD function:
SELECT MOD(level - 1,5) + 1
FROM dual
CONNECT BY level <=20;
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5

Oracle SQL - Running Sum based on group by and condition

I have table that looks like
ID SEQ LABEL COUNT
1 1 0 3
1 2 0 2
1 3 0 6
1 4 1 2
1 5 0 3
1 6 0 5
2 1 0 2
2 2 1 1
2 3 0 3
I would like to create a column called running_count. It calculates cumulative sum of the column count till the Label is 1 and then reset and start cumulative sum again.
Expected Output:
ID SEQ LABEL1 COUNT1 RUNNING_COUNT
1 1 0 3 3
1 2 0 2 5
1 3 0 6 14
1 4 1 2 16
1 5 0 3 3
1 6 0 5 8
2 1 0 2 2
2 2 1 1 3
2 3 0 3 3
I tried the following query
SELECT A.*, SUM(COUNT1) over (partition by ID,LABEL1 order by SEQ) as RUNNING_COUNT FROM TABLE_1 A
The problem here is that the cumulative sum stops in previous row(Seq) for Label = 1. I need to get the running sum till Label = 1 for Each ID based on Seq.
The Wrong Output I am getting
ID SEQ LABEL1 COUNT1 RUNNING_COUNT
1 1 0 3 3
1 2 0 2 5
1 3 0 6 14
1 4 1 2 2
1 5 0 3 3
1 6 0 5 8
2 1 0 2 2
2 2 1 1 1
2 3 0 3 3
You could make a first window sum() to define the groups, then use it as partition for the outer query:
select
t.*,
sum(count1) over(partition by id, grp order by seq) running_count
from (
select
t.*,
sum(label) over(partition by id order by seq desc) grp
from mytable t
) t
Demo on DB Fiddle:
ID | SEQ | LABEL | COUNT1 | GRP | RUNNING_COUNT
-: | --: | ----: | -----: | --: | ------------:
1 | 1 | 0 | 3 | 1 | 3
1 | 2 | 0 | 2 | 1 | 5
1 | 3 | 0 | 6 | 1 | 11
1 | 4 | 1 | 2 | 1 | 13
1 | 5 | 0 | 3 | 0 | 3
1 | 6 | 0 | 5 | 0 | 8
2 | 1 | 0 | 2 | 1 | 2
2 | 2 | 1 | 1 | 1 | 3
2 | 3 | 0 | 3 | 0 | 3

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;

sum values grouping sets of columns in postgresql 9.6

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)

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