Unique & repeating row numbers for duplicate rows in a table - sql

I have a table with a column called 'ID'
ID column has 8 rows with values 100,100,100,200,200,300,300,300
I want to create a new column called 'Row_ID' which should look up at the ID column and give unique row number to each row where a duplicate id is found and restart the counter when a different value is found.
Example , for the above values of ID columns, the Row column should look like
1,2,3,1,2,1,2,3

For Oracle Database
SELECT ROW_NUMBER()
OVER (PARTITION BY ID ORDER BY ID) AS "ROW_ID"
FROM (
SELECT 100 ID FROM dual
UNION ALL
SELECT 100 ID FROM dual
UNION ALL
SELECT 100 ID FROM dual
UNION ALL
SELECT 200 ID FROM dual
UNION ALL
SELECT 200 ID FROM dual
UNION ALL
SELECT 300 ID FROM dual
UNION ALL
SELECT 300 ID FROM dual
UNION ALL
SELECT 300 ID FROM dual
)

Related

Oracle Select max where a certain key is matched

i'm working with oracle, plSql, i need to query a table and select the max id where a key is matched, now i have this query
select t.* from (
select distinct (TO_CHAR(I.DATE, 'YYMMDD') || I.AUTH_CODE || I.AMOUNT || I.CARD_NUMBER) as kies, I.SID as ids
from transactions I) t group by kies, ids order by ids desc;
It's displaying this data
If i remove the ID from the query, it displays the distinct keys (in the query i use the alias KIES because keys was in blue, so i thought it might be a reserved word)
How can i display the max id (last one inserted) for every different key without displaying all the data like in the first image??
greetings.
Do you just want aggregation?
select thekey, max(sid)
from (select t.*,
(TO_CHAR(t.DATE, 'YYMMDD') || t.AUTH_CODE || t.AMOUNT || t.CARD_NUMBER) as thekey,
t.SID
from transactions t
) t
group by thekey
order by max(ids) desc;
Since you haven't provided data in text format, its difficult to type such long numbers and recreated the data.
However I think you can simply use the MAX analytical function to achieve your results.
with data as (
select 1111 keys,1 id from dual
union
select 2222, 1 from dual
union
select 1111, 2 from dual
union
select 2222,3 from dual
union
select 9999, 1 from dual
union
select 1111, 5 from dual
)
select distinct keys, max(id) over( partition by (keys)) from data
This query returns -
KEYS MAX(ID)OVER(PARTITIONBY(KEYS))
1111 5
9999 1
2222 3

replacement of Offset Limit in SQL Server

We have DataTemp table which has the records in desc order.
select * from (
select 9,'a',3 union
select 8,'a',2 union
select 7,'b',3 union
select 6,'a',1 union
select 5,'b',2 union
select 4,'c',3 union
select 3,'c',2 union
select 2,'b',1 union
select 1,'c',1
) door (sno,id, N_th_Reocord)
sno - Auto Id.
id - code of the Doors*.
N_th_Record - for denoting the n the record.
At a time, only three* records per Door are need to store on this table. For example Door 'a' has new entry(means 4th record) then first of 'a' Door need to delete.
4th record:
select * from (
select 10,'a',4 union --- new entry
select 9,'a',3 union
select 8,'a',2 union
select 7,'b',3 union
select 6,'a',1 union -- need to delete
select 5,'b',2 union
select 4,'c',3 union
select 3,'c',2 union
select 2,'b',1 union
select 1,'c',1
) door (sno,id, N_th_Reocord)
I do following query. But I need easiest way for deleting the row. Because, we are try to reduce the time consumption of over all project.
delete from door where sno = (
select sno from (
select 10,'a',4 union
select 9,'a',3 union
select 8,'a',2 union
select 7,'b',3 union
select 6,'a',1 union
select 5,'b',2 union
select 4,'c',3 union
select 3,'c',2 union
select 2,'b',1 union
select 1,'c',1
) door (sno,id, N_th_Reocord)
where id = 'a'
order by sno desc -- For 'DataTemp' *order by* is no needed.
offset 3 rows fetch next 1 rows only
)
Note:
Three rows and three Door are given for example. Actually we work with 144 rows per 12 Doors.
Before this delete, we check lot of Business rules.
Version: SQL Server 2012
You could use ROW_NUMBER:
WITH cte AS (SELECT *,ROW_NUMBER() OVER(PARTITION BY id ORDER BY sno DESC) rn FROM t)
DELETE FROM cte WHERE rn > 3;
db<>fiddle demo

How can I add two columns sequentially (and not concatenate)?

I am trying to pull two tables from an Oracle SQL database, and want to join them sequentially, so they appear as if they are one list.
List one has items [1,2,3,4]
List two has items [a,b,c,d]
I want to output [1,2,3,4,a,b,c,d]
Any thoughts?
One option uses a UNION with a computed column:
SELECT val
FROM
(
SELECT val, 1 AS position FROM table1
UNION ALL
SELECT val, 2 AS position FROM table2
) t
ORDER BY
position, val;
Demo
Note that I assume that all data here is text. If not, e.g. the first table be numeric, then we would have to do a cast along the way. But, this is not the main focus of your question anyway.
SELECT id_1, value_column1 from table_1
UNION
SELECT id_2, value_column2 from table_2;
if the types of columns are different - make sure you cast/convert them to char() - the resulting type should be same.
https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries004.htm
use union, i think 1,2,3 as numeric value that why converted it on varchar as for union you have to same data type
with t1 as (
select 1 as id from dual union all
select 2 from dual union all
select 3 from dual union all
select 4 from dual
), t2 as (
select 'a' as item from dual union all
select 'b' from dual union all
select 'c' from dual union all
select 'd' from dual
)
select cast(id as varchar(20)) as id from t1
union
select * from t2
demo
output
1
2
3
4
a
b
c
d

Condition in subquery- select one value if subquery return 2 records else the actual value

I have a subquery inside a big query which returns multiple values sometime and some time only one value. Below is my query and the returned values
select tran.customer_type from transaction_record tran where tran.TRANSACTION_ID=txn.id
customer_type can be 2 records - "LP" and "NA"
or
customer_type can be 2 records - "SOEMTHING ELSE" and "NA"
or
customer_type can be 1 records - "NA"
Here my probem is if i have 2 records i have to print value without NA and if i have one record i have to print what ever be the value is
Not exectly efficient (2 queries), but it should work!
Inner query counts status, id combinatios per group and outer query
removes all NA statuses that have another record on same ID.
Innermost query is just for table simulation (I like it more than create table, insert scripts).
SELECT * FROM
(
SELECT status, id, count(*)
OVER (PARTITION BY id ORDER BY 3 ) AS rn
from (
SELECT 'NA' status, 1 id FROM dual
UNION ALL
SELECT 'LP' status, 1 id FROM dual
UNION ALL
SELECT 'NA' status, 2 id FROM dual
UNION ALL
SELECT 'SOEMTHING ELSE' status, 2 id FROM dual
UNION ALL
SELECT 'NA' status, 3 id FROM dual
UNION ALL
SELECT 'NA' status, 5 id FROM dual
UNION ALL
SELECT 'LP' status, 5 id FROM dual
UNION ALL
SELECT 'NA' status, 6 id FROM dual
UNION ALL
SELECT 'SOEMTHING ELSE' status, 6 id FROM dual
UNION ALL
SELECT 'NA' status, 22 id FROM dual
))
WHERE NOT (status = 'NA' AND rn=2)

Changing columns to rows in oracle

I need to convert the result of the below query into row output.
select 'Purchase','Sale','Discount','Out of Stock' from dual
Output:
Purchase
Sale
Discount
Out of Stock
You have to use UNPIVOT to get it. UNPIVOT is opposite of PIVOT and it converts column values to
with tbl(col1,col2,col3,col4) as
(
select 'Purchase','Sale','Discount','Out of Stock' from dual
),tbl2 as(
SELECT *
FROM tbl UNPIVOT (dat for col in (col1,col2,col3, col4)))
select dat from tbl2
If you have 1 more row, then it is better to populate the column names also like below.
with tbl(col1,col2,col3,col4) as
(
select 'Purchase','Sale','Discount','Out of Stock' from dual union
select 'foo','bar','data','blah' from dual
)
SELECT *
FROM tbl UNPIVOT (dat for col in (col1,col2,col3, col4));
But if you just want the values, then select only 'dat' column as in first example.
You could use UNION to have the values as different rows. For example,
SQL> WITH DATA(item) AS
2 ( SELECT 'Purchase' FROM dual
3 UNION
4 SELECT 'Sale' FROM dual
5 UNION
6 SELECT 'Discount' FROM dual
7 UNION
8 SELECT 'Out of Stock' FROM dual
9 )
10 SELECT item FROM DATA;
ITEM
------------
Discount
Out of Stock
Purchase
Sale
SQL>
Remember, union doesn't allow duplicates, so use UNION ALL if you want to allow duplicate rows.