I have a table that I would like to update in oracle. It's okay to assume that the rownum are in sequential order from 1 through 7
Table Have
1
2
3
4
4
4
4
Table Want
1
2
3
4
5
6
7
It seems that you want to have unique sequential numbers in that column.
If you don't care much about conditions, you could even
update have set col1 = rownum;
If I get you right you need something like UPDATE all your duplicated (in your case value = 4) rows by adding (rownum -1).
See example below.
create table have as
select case when rownum <= 4 then rownum else 4 end col1 from dual connect by level <= 7;
select col1 from have order by col1;
COL1
----------
1
2
3
4
4
4
4
update have
set col1 = col1 + rownum -1 where col1 = 4;
select col1 from have order by col1;
COL1
----------
1
2
3
4
5
6
7
Related
I have a relatively simple problem (I think), but I can not get my head around it. I have a single column with 200 records. The values of the rows are a list of numbers 1-200 (No duplicates). I would like to organize the numbers in 5 columns with the data sorted horizontally (Ascending A-Z). Example:
Original table:
Column1
1
2
3
4
5
6
7
8
...and so on to 200
The view result should look like this:
|Col1|Col2|Col3|Col4|Col5|
1 2 3 4 5
6 7 8 9 10
11 12 ...an so on to 200
I looked into PIVOTING but I don't think it will work.
We can try a pivot query where the group is defined as the column minus one, divided by 5. This places the first five records into the first group/row, the next five into the second group/row, and so on. Then, we pivot on each Column1 % 5 value to determine into which of the five columns each value will go.
SELECT
MAX(CASE WHEN Column1 % 5 = 1 THEN Column1 END) AS Col1,
MAX(CASE WHEN Column1 % 5 = 2 THEN Column1 END) AS Col2,
MAX(CASE WHEN Column1 % 5 = 3 THEN Column1 END) AS Col3,
MAX(CASE WHEN Column1 % 5 = 4 THEN Column1 END) AS Col4,
MAX(CASE WHEN Column1 % 5 = 0 THEN Column1 END) AS Col5
FROM yourTable
GROUP BY
(Column1 - 1) / 5;
Demo
We have an oracle table x and we have values in it in a following manner
num1 dt cd
1 24-06-2017 3
1 24-06-2017 4
2 24-06-2017 1
2 24-06-2017 2
2 24-06-2017 4
2 25-06-2017 3
2 25-06-2017 4
Now I have to delete duplicate data from this table using num1,dt , if num1 and dt have any other value instead of 4 then it should exist in table and cd=4 should be deleted. Here in below condition 3 or any other value should exist but it should not be 4
1 24-06-2017 3
1 24-06-2017 4
Now here 4 should be deleted completely for 2 , 24/06/2017 and only 1 rows of each field should exist in the table ie :2 24/06/2017 1 and 2 24/06/2017 2 should exist.
2 24-06-2017 1
2 24-06-2017 2
2 24-06-2017 4
Now in third case if we dont have any other value except 4 for num1 and date then we should have only 1 row of 4 for these dates.
3 26-06-2017 4
3 26-06-2017 4
Please provide solution for this, help will be appreciated.
Oracle conveniently has rowid, which can really help with this. Here is an approach that uses rowid:
delete from t
where t.rowid <> (select max(rowid) keep (dense_rank first
order by (case when cd = 4 then 2 else 1 end)
)
from t
where t2.num1 = t.num1 and t2.date = t.date
);
This will keep exactly one row per num1/date comparison.
If you are using Oracle 12C+, then a more intuitive form of this query is:
delete from t
where t.rowid <> (select rowid
from t
where t2.num1 = t.num1 and t2.date = t.date
order by (case when cd = 4 then 2 else 1 end)
fetch first 1 row only
);
This doesn't work in earlier versions because fetching one row requires an additional subquery -- and that subquery cannot be correlated with the outer query.
If I get your question right it might work like this:
DELETE FROM table
WHERE (num1, dt, ct) IN (SELECT num1, dt, 4
FROM table
GROUP BY num1, dt
HAVING MAX(ct) != 4
OR MIN(ct) != 4)
OR ((num, dt, ct) IN (SELECT num1, dt, MAX(ct)
FROM table
GROUP BY num1, dt
HAVING MAX(ct) = 4
AND MIN(ct) = 4)
AND rowid NOT IN (SELECT MIN(rowid)
FROM table
GROUP BY num1, dt
HAVING MAX(ct) = 4
AND MIN(ct) = 4))
I am trying to figure out the best way to determine, for a specific ID within an Oracle 11g table that has 5 columns and say 100 rows against this ID, if all the column values are the same for these five columns.
For example:
Table Name: TABLE_DATA
Columns:
TD_ID ID COL1 COL2 COL3 COL4 COL5
-----------------------------------------------------------------------
1 1 1 0 3 2 0
2 1 1 0 3 2 0
3 1 1 0 3 2 0
4 1 1 0 3 2 0
5 1 1 0 3 2 0
6 1 1 0 3 2 0
So based on the above example which is just showing 6 rows for now against the ID:1, I want to check that for all COL1, COL2, COL3, COL4 and COL5 values where ID = 1, tell me if all the values are the same from the very first row right down to the last – if so, then return ‘Y’ else return ‘N’.
Given the above example, the result would be ‘Y’ but for instance, if TD_ID = 5 and COL3 = 4 then the result would be ‘N’, as all the column values are not the same, i.e.:
TD_ID ID COL1 COL2 COL3 COL4 COL5
-----------------------------------------------------------------------
1 1 1 0 3 2 0
2 1 1 0 3 2 0
3 1 1 0 3 2 0
4 1 1 0 3 2 0
5 1 1 0 4 2 0
6 1 1 0 3 2 0
I’m just not sure what the fastest approach to determine this is, as the table I am looking at may have more than 2000 rows within the table for a specific ID.
You may also try this :
Select ID
, case when count(distinct COL1 || COL2 || COL3 || COL4 || COL5) > 1
then 'N'
else 'Y' end RESULT
From TABLE_DATA
Group by id;
In this way you group by id and counts how many distinct combination are there.
If only 1 , so all the rows have the same set of values, otherwise it don't.
See if the following is fast enough for you:
SELECT ID, CASE WHEN COUNT(*) > 1 THEN 'No' ELSE 'Yes' END As "Result"
FROM (SELECT DISTINCT ID, COL1, COL2, COL3, COL4, COL5
FROM Table_Data) dist
GROUP BY ID
Here's a little query, you might wanna try out (eventually, you just could try figuring out a better MINUS statement for you):
SELECT
CASE
WHEN ( -- select count of records from a subquery
SELECT
COUNT(1)
FROM
( -- select all rows where id = 1
SELECT
td.col1
,td.col2
,td.col3
,td.col4
,td.col5
FROM
table_data td
WHERE
td.id = 1
MINUS -- substract the first row of the table with id = 1
SELECT
td.col1
,td.col2
,td.col3
,td.col4
,td.col5
FROM
table_data td
WHERE
td.id = 1
AND ROWNUM = 1
)
) = 0 -- check if subquery's count equals 0
AND EXISTS ( -- and exists at least 1 row in the table with id = 1
SELECT
1
FROM
table_data td
WHERE
td.id = 1
AND ROWNUM = 1
) THEN 'Y'
ELSE 'N'
END AS equal
FROM
dual
I have table1 as below:
Col1 Bal
-------------------
1 0
2 0
3 0
4 0
Col1 is the key here.
I have table2 as below:
Col1 Bal Date
---------------------
1 5 x
1 10 y
1 7 z
3 8 p
3 9 m
Col1 is the join column in both tables.
I want to update bal in first table with sum of bal in 2nd table.
What would be the sql statement for this:
update table1 a set a.bal=(select sum(b.bal) from table2) where
and I am lost!
After update, table1 should be:
Col1 Bal
-------------------
1 22
2 0
3 17
4 0
From the documentation, it looks like you can use table aliases in DB2:
update table1 a
set bal = coalesce(
(
select sum(b.bal)
from table2 as b
where a.col1 = b.col1
), 0)
How can I display rows with 3 or more equal data in a column for example:
1
1
1
2
2
3
3
3
so that my select on displays
1
3
SELECT YourColumn
FROM YourTable
GROUP BY YourColumn
HAVING COUNT(*) >= 3;