update incremental values into an SQL column - sql

I'm looking for some help with the following query:
I have a bunch of rows with column TYPE, VERSION - however in some cases the version got messed up so I want to rewrite it.
Basically, it now looks this:
Type, Version
A, 0
A, 0
A, 1
A, 2
B, 1
B, 3
I want it to look like this:
Type, Version
A, 0
A, 1
A, 2
A, 3
B, 0
B, 1
Any help would be greatly appreciated,
Thanks

WITH T AS
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY Type ORDER BY Version) - 1 AS V
FROM YourTable
)
UPDATE T
SET Version = V

Related

SQL Query get common column with diff values in other columns

I am not very fluent with SQL.. Im just facing a little issue in making the best and efficient sql query. I have a table with a composite key of column A and B as shown below
A
B
C
1
1
4
1
2
5
1
3
3
2
2
4
2
1
5
3
1
4
So what I need is to find rows where column C has both values of 4 and 5 (4 and 5 are just examples) for a particular value of column A. So 4 and 5 are present for two A values (1 and 2). For A value 3, 4 is present but 5 is not, hence we cannot take it.
My explanation is so confusing. I hope you get it.
After this, I need to find only those where B value for 4 (First Number) is less than B value for 5 (Second Number). In this case, for A=1, Row 1 (A-1, B-1,C-4) has B value lesser than Row 2 (A-1, B-2, C-5) So we take this row. For A = 2, Row 1(A-2,B-2,C-4) has B value greater than Row 2 (A-2,B-1,C-5) hence we cannot take it.
I Hope someone gets it and helps. Thanks.
Rows containing both c=4 and c=5 for a given a and ordered by b and by c the same way.
select a, b, c
from (
select tbl.*,
count(*) over(partition by a) cnt,
row_number() over (partition by a order by b) brn,
row_number() over (partition by a order by c) crn
from tbl
where c in (4, 5)
) t
where cnt = 2 and brn = crn;
EDIT
If an order if parameters matters, the position of the parameter must be set explicitly. Comparing b ordering to explicit parameter position
with params(val, pos) as (
select 4,2 union all
select 5,1
)
select a, b, c
from (
select tbl.*,
count(*) over(partition by a) cnt,
row_number() over (partition by a order by b) brn,
p.pos
from tbl
join params p on tbl.c = p.val
) t
where cnt = (select count(*) from params) and brn = pos;
I assume you want the values of a where this is true. If so, you can use aggregation:
select a
from t
where c in (4, 5)
group by a
having count(distinct c) = 2;

(SQL) How to compare each row to all other rows in Presto

I'm working with AWS Athena which uses Presto. Let's say I have a SQL table with columns A, B, C, and D. Assume table is sorted by column C, ascending.
I need to compare each row to all the other rows and check if current row's D value is the maximum value out of all rows whose C values are less than current row's C value. Then append a boolean value in column F. Code in Python would look something like:
D_val_list = []
for index, row in df.iterrows():
max_val_D = df[:index]['D'].max() #Sorted on column C
if row['D'] < max_val_D:
D_val_list.append(FALSE)
else:
D_val_list.append(TRUE)
df['F'] = D_val_list
Using the provisional jupyter notebook in Athena times out (the dataset is millions of rows long) and I figure connecting to AWS via local jupyter instance would have similar issues.
In SQL, you would use window functions -- something like this:
select t.*,
(case when d < coalesce(max(d) over (order by c
rows between unbounded preceding and 1 preceding) is null,
d + 1
then 1 else 0
end) as flag
from t;
This logic would work assuming that c is unique. That said, there might be alternative depending on the exact nature of the data.
You have to discretely order your rows on c in Athena because of its distributed nature. You can use window functions on top of the ordered set to achieve your desired results:
SELECT
a,
b,
c,
d,
CASE WHEN d>lag(max_so_far) OVER () THEN true ELSE false END as f
FROM (
SELECT a,
b,
c,
d,
max(d) OVER (rows BETWEEN unbounded preceding AND current row) AS max_so_far
FROM (
-- sorted ON c
SELECT
a,
b,
c,
d
FROM dataset.table
ORDER BY c
)
)

SQL Group by on multiple columns

My input is:
a b c
-------
A 5 3
A 4 2
B 3 1
B 5 3
I would like to get all a values having the same values in b and c, so the output should be as:
{A,B} 5 3
I am using the group by, but I am not achieving my goal.
In standard SQL, this would look like:
select b, c, listagg(a, ',') within group (order by a)
from t
group by b, c;
Not all databases support listagg(), but most have a method for concatenating strings.
In Hive, you would use collect_list() or collect_set():
select b, c, collect_list(a, ',')
from t
group by b, c;
You can convert the array back to a string, but I recommend keeping it as an array.

Counting the amount of object with the same value in another column

I want to count the amount of an occurrance the reattacht that the row back and couldn't find any good way to do it.
So 1 table would look like
id | value
1. a
2. a
3. b
4. a
5. b
6. b
7. c
8. c
9. a
which I would like to result in:
id | value | count
1. a, 4
2. a, 4
3. b, 3
4. a, 4
5. b, 3
6. b, 3
7. c, 2
8. c, 2
9. a, 4
I can only find answers with group by so any help is appreciated. This should also be matched to another table so if the result is joinable that would be helpful as well.
If your RDBMS support window functions, no need to join: you can just do a window count:
select t.*, count(*) over(partition by value) cnt from mytable t
select t.id, t.value, tmp.cnt
from your_table t
join
(
select value, count(*) as cnt
from your_table
group by value
) tmp on tmp.value = t.value

how to mix 2 tables(A,B) in 1 table (AB) with sql (db2 dialog) with special order between records

Please how to mix 2 tables(A,B) in 1 table(AB) with special order.
It is 2 tables, A and B with only 1 col. So it is a list/array.
I must order the row like this:
A.col1,A.col1,B.col1,B.col1,A.col1,A.col1,B.col1,B.col1,A.col1,A.col1,B.col1,B.col1 and so on.
To see it easily, it must be:
A,A,B,B,A,A,B,B,A,A
So 2 row from A, 2 row from B, 2 row from A, 2 row from B and so on
I would prefer with db2 sql dialog language, but if it isnt specific would be useful in any sql dialog
thanks
Try this:
SELECT Field1 FROM
(SELECT Field1, 1 AS S, ROW_NUMBER() OVER() AS N, FLOOR(ROW_NUMBER() OVER()/2) AS G FROM A
UNION ALL
SELECT Field1, 2 AS S, ROW_NUMBER() OVER() AS N, FLOOR(ROW_NUMBER() OVER()/2) AS G FROM B)
ORDER BY G, S, N
That should work in DB2. Unfortunately I don't have a DB2 database handy to test it so the code goes without any warranty.