Keep IDs in sequential order after deleing a row [duplicate] - sql

This question already has an answer here:
Renumbering sequence numbers
(1 answer)
Closed 6 months ago.
I have a Microsoft Access Database table, where i use the "Id" value in order to gather the information in that row.
Example:
Id Name Surname
1 Jim Smith
2 Luis Evans
3 Charles Holland
4 John Price
I have a Query which is used to delete one of the rows of this table, however when i delete a row in the table the Id values don't stay in a sequential order. For exmaple if i delete the id 2 row the table will look like this:
Id Name Surname
1 Jim Smith
3 Charles Holland
4 John Price
How do i make it so when I delete a row in the table the Ids stay in sequential order? Like this:
Id Name Surname
1 Jim Smith
2 Charles Holland
3 John Price

You can use a sub-query to get the "question number". Something like this:
SELECT Q.ID, Q.ForeName, Q.Surname,
(SELECT COUNT (*) FROM tblQuestion AS Q1 WHERE Q1.ID<=Q.ID) AS QuestionNo
FROM tblQuestion AS Q
ORDER BY Q.ID ASC;
This counts the number of records that have an ID less than or equal to the ID of the current record. So, in the table with 1 record deleted, ID 1 has 1 record (ID 1), ID 3 has two records (ID 1 and 3), and ID 4 has three records (ID 1, 3 and 4).
Note that Name is a reserved word, so you should use a different name for the field.

you can get temporary data like this
select ROW_NUMBER() over(order by Id) As Id,Name,Surname From TableData

Related

PostgreSQL: how to delete duplicated rows grouped by the value of a column?

Given the following table, I need to delete every row corresponding to a certain "id" whenever all these rows are duplicated in a successive "id". Note that the deletion all rows for a specific "id" should happen only in case that every row between the two ids match (with the exception of the different "id" column).
id
name
subject
score
1
Ann
Maths
9
1
Ann
History
8
2
Ann
Maths
9
2
Ann
History
8
3
Ann
Maths
9
3
Ann
History
7
4
Bob
Maths
8
4
Bob
History
8
For this specific input, the updated output table should be:
id
name
subject
score
1
Ann
Maths
9
1
Ann
History
8
3
Ann
Maths
9
3
Ann
History
7
4
Bob
Maths
8
4
Bob
History
8
This because all records between id 1 and 2 are the exactly the same. This doesn't apply for "id" 1 and 3, as long as there's at least one row not in common between the two (id 1 has 8 in History while id 3 has 7 in the same subject).
So it is not as simple as deleting duplicated rows. Here's my attempt:
DELETE FROM table a
USING table b
WHERE a.name = b.name
AND a.subject = b.subject
AND a.score = b.score
AND a.ID < b.ID;
Can you help me?
You can first get all ids that shouldn't be deleted and then exclude them in the WHERE clause of the DELETE statement.
Step 1. In order to match unique ids that are not repeated for all rows, you can use PostgreSQL DISTINCT ON construct, that will allows you to get every row that is not duplicated on the fields "name", "subject", "score". Then retrieve these ids only once with a simple DISTINCT.
SELECT DISTINCT id
FROM (SELECT DISTINCT ON (name, subject, score) id
FROM tab
ORDER BY name, subject, score, id) ids_to_keep
Step 2. Hence you can build the DELETE statement using the NOT IN operator inside the WHERE clause:
DELETE FROM tab
WHERE id NOT IN (
SELECT DISTINCT id
FROM (SELECT DISTINCT ON (name, subject, score) id
FROM tab
ORDER BY name, subject, score, id) ids_to_keep
);
Check the demo here.

How to order by number ASC but force to order same value from another field in SQL?

Let say I have a table like this:
Sequence
Name
2
John D
4
Alex H
5
John M
1
Sell T
3
John D
2
Alex H
I want it ordered like this
Sequence
Name
1
Sell T
2
Alex H
4
Alex H
2
John D
3
John D
5
John M
To order by the sequence field but if the name field has values that are the same, on the first occurence of the next row then all same name should fall under it respecting the order of the sequence as well.
I prefer t-sql solution.
The example data and ambiguous explanation suggest that you just want two order by keys:
order by sequence, name
However, I suspect that you want to order names by their minimum sequence. If so, you can use window functions:
order by min(sequence) over (partition by name), name, sequence
For your sample data, these would result in the same ordering.

How to select all duplicate rows except original one?

Let's say I have a table
CREATE TABLE names (
id SERIAL PRIMARY KEY,
name CHARACTER VARYING
);
with data
id name
-------------
1 John
2 John
3 John
4 Jane
5 Jane
6 Jane
I need to select all duplicate rows by name except the original one. So in this case I need the result to be this:
id name
-------------
2 John
3 John
5 Jane
6 Jane
How do I do that in Postgresql?
You can use ROW_NUMBER() to identify the 'original' records and filter them out. Here is a method using a cte:
with Nums AS (SELECT id,
name,
ROW_NUMBER() over (PARTITION BY name ORDER BY ID ASC) RN
FROM names)
SELECT *
FROM Nums
WHERE RN <> 1 --Filter out rows numbered 1, 'originals'
select * from names where not id in (select min(id) from names
group by name)

how to get last value of any attribute in postgresql pivot table

I have a table like this
id u_id attr_key attr_value process_id insert_time
------|-------|----------|------------|--------------|--------------
1 1 name john 1 1
2 1 family smith 1 2
3 2 job clerk 2 3
4 1 name sarah 3 4
.............
I have to find two things:
I have to create a view by tablefunc(crosstab) to fetch a group of data for any of u_id ..so it's simple
I have to find (realtime) last value of any key of any u_id (like Hbase database) so I don't have any good solution
this is what i need
id u_id attr_key attr_value
------|-------|----------|------------
4 1 name sarah
2 1 family smith
Any idea or function?
(its possible to add a column in my data model )
The most efficient solution to greatest-n-per-group problems in Postgres is to use distinct on ():
The following will retrieve that for a single u_id
select distinct on (attr_key) id, u_id, attr_key, attr_value
from the_table
where u_id = 1
order by attr_key, insert_time desc;
An index on (u_id, attr_key, insert_time) should help for performance

Splitting the data through SSIS

I have a table "Employee" as shown below
Id Name
1 John
2 Jaffer
3 Syam
4 Aish
5 Gidson
1 Aboo
2 Sindhu
3 Saravanan
I want to get two outputs like
Id
1
2
3
Id
4
5
Which transformation should i use?
Could you Please help on that?
You will have to write two queries.
SELECT Id
FROM Employee
GROUP BY Id
HAVING COUNT(Id)>1
The above query will give you first output
SELECT Id
FROM Employee
GROUP BY Id
HAVING COUNT(Id)=1
This will give you 2nd output.