Insert duplicate rows from temporary table - sql

I am confused how to insert values from the declared table to the selected table. I used except to prevent insert of the first duplicate, but I want to make the second row of the duplicate be inserted.
How can I put the second value to the table above?
My point to achieve here is to insert the second value in the primary table to manipulate is time_mode value.
This is my query
INSERT INTO temp_time(SwipeID,tdate,ttime,time_mode,raw_data,[Shift],eid,machineip)
SELECT a.SwipeID,a.tdate,a.ttime,a.time_mode,a.raw_data,1, eid FROM #temp_time
EXCEPT
SELECT SwipeID,tdate,ttime,time_mode,raw_data,Shift,eid,machineip from temp_time
From the query above, only one value is inserted. My clients changed their minds that they want the duplicated values to be reflected. Changing the values on time_mode can be changed by the system i made. If I use the query again using insert without the except value, there would be 3 rows for the primary table which causes a problem because what I wanted to reflect is only the 2 rows.

I think I finally understood your problem correctly. Assuming you already have ran your first query that inserted the data without duplicates in your second table and now you want to insert the rest of the original duplicates.
In that case here's how you may do it, by eliminating the previous rows that you already have inserted:
WITH dupes AS (
SELECT *, ROW_NUMBER() OVER(
PARTITION BY SwipeID, tdate, ttime, time_mode, raw_data,[Shift], eid, machineip
ORDER BY (SELECT(0))
) AS row_num
FROM SourceTable
)
INSERT INTO DestinationTable (/*columns*/)
SELECT /*values you need*/
FROM dupes
WHERE row_num > 1;

Assuming you are using MYSQL;
INSERT INTO your_first_table(SwipeID,tdate,ttime,time_mode,raw_data,shift,eid,machineip)
SELECT a.SwipeID,a.tdate,a.ttime,a.time_mode,a.raw_data,1,a.eid,a.machineip FROM your_second_table a ORDER BY a.SwipeID DESC LIMIT 1, 1

Related

SQL call Max row number from a temp table

In the temp table there are only two columns available. I would like to get the most recent ID for each load, as shown in the picture below.
I have tried this but it doesn't give me the answer I need.
select max(rn_plus_1),a.load, a.id from( select a.load,
a.id,
ROW_NUMBER() over(order by a.id desc) rn from max_num a group by load
, id) a
TEMP_TABLE lacks a sequential primary key or any other indicator for order of insertion. So it is not possible to get the latest ID for a LOAD using the columns of the table itself.
However, there is one option: ORA_ROWSCN(). This is a pseudo-column which identifies the System Change Number for the transaction which changed the table. So we can reconstruct the order of insertion by sorting the table on ORA_ROWSCN.
There are some caveats:
By default the SCN applies to the block level. Consequently all the rows in a block have the same SCN. It's a good enough approximation for wide tables but hopeless for a two-column toy like TEMP_TABLE. We can track SCN at the row level but only if the table is created with ROWDEPENDENCIES. The default is NOROWDEPENDENCIES. Unfortunately, we cannot use ALTER TABLE here. You will need to drop and recreate the table (*) to enable ROWDEPENDENCIES.
The SCN applies to the transaction. This means the solution will only work if each row in TEMP_TABLE is inserted in a separate transaction.
Obviously this is only possible if TEMP_TABLE is an actual table and not a view or some other construct.
Given all these criteria are satisfied here is a query which will give you the result set you want:
select load, id
from ( select load
, id
, row_number() over (partition by load order by ora_rowscn desc) as rn
from temp_table
)
where rn = 1
There is a demo on db<>fiddle. Also, the same demo except TEMP_TABLE defined with NOROWDEPENDENCIES, which produces the wrong result.
(*) If you need to keep the data in TEMP_TABLE the steps are:
rename TEMP_TABLE to whatever;
create table TEMP_TABLE as select * from whatever rowdependencies;
drop table whatever;
However, the SCN will be the same for the existing rows. If that matters you'll have to insert each row one at a time, in the order you wish to preserve, and commit after each insert.

Update one from two of duplicates in Firebird – more rows

How do I update one from two or more duplicate rows? I want to keep one and update the others with a new value.
Simple example tables:
from
one|two|three
----------
1|milk|water
1|milk|water
to
one|two|three
----------
1|milk|water
1|milk|sugar
http://www.ibexpert.net/ibe/index.php?n=Doc.TheMysteryOfRDBDBKEY
Select *, RDB$DB_KEY from MyExampleTable;
then
Update MyExampleTable
Set Column=Value
Where RDB$DB_KEY=xxxxx;
Another approach would be using Stored Procedure (or Execute Block) and use SQL Cursor variables. But that would require careful loop management, so you would skip one row and change 2nd, third and so on.
https://www.firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-psql-coding.html#fblangref25-psql-tbl-declare-cursor
Also see examples for UPDATE ... WHERE CURRENT OF ... at
https://www.firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-dml-update.html#fblangref25-dml-tbl-update
But probably most proper way would be to add unique Primary Key column to that table and then use that unique numeric ID
Don't know which version of Firebird you are using (analytic functions are supported as of version 3.0) and if the following syntax is valid (I wasn't able to verify that at the moment), you could do this:
update table
set three='sugar'
where row_number() over (partition by one, two)=1
Otherwise, another, more convoluted way to do it would be: (untested)
select one, two, three
from (
select t1.one
,t1.two
,coalesce(t2.three, t1.three) as three
,row_number() over (partition by t1.one, t1.two) as row_num
from table t1
left join (
select one, two, 'sugar' as three, 1 as row_num
from (
select distinct one, two, three
from table
group by one, two, three
having count(*) > 1
)
) t2
on t1.one=t2.one
and t1.two=t2.two
and t1.row_num=t2.row_num
)

Select into with max()

I have a basic query I use to determine the max value of a column in a table:
select A.revenue_code_id, max(A.revenue_code_version) from rev_code_lookup A
group by A.revenue_code_id
This results in ~580 rows (the entire table has over 2400 rows).
This works just fine for my query results but what I don't know is how to insert the 580 rows into a new able based on the max value. I realize this isn't the right code but what I am thinking of would look something like this:
select * into new_table from rev_code_lookup where max(revenue_code_version)
You can use the row_number() function to get the data you want. Combine with the other answer to insert the results into a table (I've made up a couple of extra columns as an example):
Select
x.revenue_code_id,
x.revenue_code_version,
x.update_timestamp,
x.updated_by
From (
Select
revenue_code_id,
revenue_code_version,
update_timestamp,
updated_by,
row_number() over (partition by revenue_code_id Order By revenue_code_version Desc) as rn
From
revenue_code_lookup
) x
Where
x.rn = 1
Example Fiddle
The insert in another table is always the same way, no matter the complexity of your select:
insert into table
[unbeliavablycomplicatedselecthere]
So in your case:
insert into new_table
select A.revenue_code_id, max(A.revenue_code_version) from rev_code_lookup A
group by A.revenue_code_id
Similarly, if you need to create a brand new table, do this first:
CREATE TABLE new_table
AS
select A.revenue_code_id, max(A.revenue_code_version) from rev_code_lookup A
group by A.revenue_code_id
This will create the corresponding table schema and then you can execute the previous query to insert the data.

Deleting Duplicate Records from a Table

I Have a table called Table1 which has 48 records. Out of which only 24 should be there in that table. For some reason I got duplicate records inserted into it. How do I delete the duplicate records from that table.
Here's something you might try if SQL Server version is 2005 or later.
WITH cte AS
(
SELECT {list-of-columns-in-table},
row_number() over (PARTITION BY {list-of-key-columns} ORDER BY {rule-to-determine-row-to-keep}) as sequence
FROM myTable
)
DELETE FROM cte
WHERE sequence > 1
This uses a common table expression (CTE) and adds a sequence column. {list-of-columns-in-table} is just as it states. Not all columns are needed, but I won't explain here.
The {list-of-key-columns] is the columns that you use to define what is a duplicate.
{rule-to-determine-row-to-keep} is a sequence so that the first row is the row to keep. For example, if you want to keep the oldest row, you would use a date column for sequence.
Here's an example of the query with real columns.
WITH cte AS
(
SELECT ID, CourseName, DateAdded,
row_number() over (PARTITION BY CourseName ORDER BY DateAdded) as sequence
FROM Courses
)
DELETE FROM cte
WHERE sequence > 1
This example removes duplicate rows based on the CoursName value and keeps the oldest basesd on the DateAdded value.
http://support.microsoft.com/kb/139444
This section is the key. The primary point you should take away. ;)
This article discusses how to locate
and remove duplicate primary keys from
a table. However, you should closely
examine the process which allowed the
duplicates to happen in order to
prevent a recurrence.
Identify your records by grouping data by your logical keys, since you obviously haven't defined them, and applying a HAVING COUNT(*) > 1 statement at the end. The article goes into this in depth.
This is an easier way
Select * Into #TempTable FROM YourTable
Truncate Table YourTable
Insert into YourTable Select Distinct * from #TempTable
Drop Table #TempTable

Incrementing value based on criteria in a single database query

I have a table which has a column labeled 'sortorder' which is used to allow customer to manually change the order of each item. The table also has a column labeled 'CategoryId'.
I was curious, if I was bulk importing a set of data in which I knew all data, including CategoryId, how I could specify the incrimenting value for 'SortOrder' inside the query, so that it went from 1 to X within each unique CategoryId.
Thanks everyone.
I'm not sure I understand your question but I think what you're asking is how to synthesize an appropriate SortOrder during an insert into the table. You should use ROW_NUMBER() with partitioning by CategoryId. Of course you will need to define a sorting criteria that gives the propert order of '1 to X':
INSERT INTO myTable (SortOrder, CategoryId, <other columns> ...)
SELECT ROW_NUMBER() OVER (PARTITION BY CategoryId ORDER BY mySortCriteria)
, CategoryId
, <other columns> ...
FROM SourceTable;
Sounds like you're needing to use the row_number function in your import.
INSERT MyTable(SortOrder, ...)
SELECT SortOrder = row_number() over (partition by CatgoryID order by SomeOtherField), ...
FROM MyTable
For anyone who might come along later who is still in SQL Server 2000, here is another way to accomplish the task.
Using a staging table of some sort to fix up the data from the bulk insert. Make sure it has a column called sortorder which is initally populated with a 1 and an identity based id column.
then you can update this with a self join, something like
update t
set sortorder = t1.sortorder +1
from test t
join Test t1 on t.id = t1.id+1
Then put the data into your prod table.