Update rows with previous rows - sql

I have a table with a column 'id' which is autoincrement. In some records i have zero values. I want to update them by their previous rows (here previous means id - 1) .
How can i do that?
This query returns those records with zero values:
SELECT * FROM myTable
WHERE col1 = 0
which returns:
id col1 col2 ..... coln
15 0 0 0
23 0 0 0

You could use a correlated subquery:
update mytable t
set col1 = (select t1.col1 from mytable t1 where t1.id = t.id - 1)
where col1 = 0

Related

SQL except a query result

TEST table has 315,729,533 records in total
Using the following query I get One set of result -
SELECT count(*)
from test
where Col1 <> '' and Col2='U'
34,270,975
I want a Query that can provide me another set of result that gived me Total - last query result (315,729,533-34,270,975 = 281,458,558)
Records for each Col & Col2 are as follows -
Col1 Count
NULL 638
282221444
~ 48
C 34724501
D 37055
F 11
N 3144
Col2 Count
D 3621131
M 1772356
U 311593354
Will appreciate inputs.
You would use:
select count(*)
from test
where (Col1 = '' or Col1 is null) or
(Col2 <> 'U' or Col2 is null);

Query with 'OR' condition returns no records

I tried to get some records from PostgreSQL DB but it returns no records when I add OR condition.
e.g.:
select * from table where col1 = 'A'
returns: 5k records
select * from table where col1 = 'A' and col2 <> 1
returns: 3k records
select * from table where (col1 = 'A' and col2 <> 1) or (col1 = 'B')
returns: 0 records
Please advise what am I doing wrong?

SQL Deleting All Records If ColA Matches and ColB Matches Sometimes

I need to delete all records from a SQL table where ColumnA matches an ID that sometimes has ColumnB equal 0. In other words, if any data for an ID is bad, get rid of all data.
ColumnA ColumnB
------- -------
11 0
11 1
11 0
12 1
12 1
In this data, I would want to delete anything where ColumnA is 11 because sometimes ColumnB is 0.
The ANSI standard syntax is:
delete from t
where exists (select 1
from t t2
where t2.ColumnA = t.ColumnA and t2.ColumnB = 0
);
You can also use in:
delete from t
where t.ColumnA in (select t2.ColumnA
from t t2
where t2.ColumnB = 0
);
As easy as:
delete from tablename
where columnA in (select columnA from tablename where columnB = 0)

Hive - Select query returns 1 or 0 based on lookup table values

In Select query I need to return 1 or 0 based on another lookup table values.
Table1:
Column1 Column2
S 0
Table2:
Column1
A
F
S
Table1 Column1 value S is available in Table2 Column1 value, so I want to return 1 in select query.
How do i write a SELECT query like that?
select Table2.Column1, if(!isnull(Table1.Column1), 1, 0)
from Table1 RIGHT JOIN Table2 ON Table1.Column1 = Table2.Column1;
Output:
A 0
F 0
S 1

Messing with 'when not matched' in SQL (how to merge properly)

I'm creating several tables and merging data from them into one. These tables have similar columns col1 and col2 but the values in these columns can be different, ex. col1 on row 1 from tab1 may have "0" and col1 from tab2 may have on the same row in col1 "1". ONLY in this case I need to update the value from tab1 in col1 on the row 1. Take a look at the following example:
BEFORE MERGING
tab1:
id col1 col2
1 0 0
2 0 1
3 0 0
AFTER MERGING WITH tab2
tab2: tab1:
id col1 col2 id col1 col2
1 1 0 ---> 1 1 0
2 0 0 2 0 1
3 0 0 3 0 0
For that purpose I use the following query:
merge into tab1 st
using (select id, col1, col2 from tab2) ss
ON (st.id=ss.id)
when matched then
update set st.col1 = ss.col1,
st.col2 = ss.col2
where ss.col1 != 0 or ss.col2 != 0
when not matched then
insert (st.id, st.col1, st.col2)
values (ss.id, ss.col1, ss.col2)
;
I'm just learning sql so only now I noticed that this query is not correct. It can overwrite the "1" value in the tab1 with "0" coming from tab2. Help me to improve this query please, I'm stuck.
You can use a CASE expression when setting the values to control which value gets assigned. Try something like:
merge into tab1 st
using (select id, col1, col2 from tab2) ss
ON (st.id=ss.id)
when matched then
update set st.col1 = CASE WHEN st.col1 = 0 THEN ss.col1 ELSE st.col1 END,
st.col2 = CASE WHEN st.col2 = 0 THEN ss.col2 ELSE st.col2 END
where ss.col1 != 0 or ss.col2 != 0
when not matched then
insert (st.id, st.col1, st.col2)
values (ss.id, ss.col1, ss.col2)
;
Thus in the WHEN MATCHED situation, if the value from tab1 (st) is zero you change it to the value from tab2 (ss), otherwise you just set the value from tabl1 to itself.
Share and enjoy.
You should update with the max of {ss.coln, st.coln}. For example, using GREATEST:
MERGE INTO tab1 st
USING (SELECT id, col1, col2 FROM tab2) ss
ON (st.id = ss.id)
WHEN MATCHED THEN
UPDATE
SET st.col1 = greatest(ss.col1, st.col1),
st.col2 = greatest(ss.col2, st.col2)
WHERE ss.col1 > st.col1
OR ss.col2 > st.col2
WHEN NOT MATCHED THEN
INSERT (st.id, st.col1, st.col2)
VALUES (ss.id, ss.col1, ss.col2);