Update table column primary key based on mapping table - sql

I have two tables.
table contains records with column A (type number, primary key).
table contains records with columns A, B (type number). The second represents mapping table.
What is the problem?
I need to do remapping all records in table 1, specifically column A to column B based on mapping table 2.
But the problem is that table 1 contains records which have also values B from table 2 (in column A). That means when I will do remapping table 1 then can appear problem with uniqueness because column A in table 1 is primary key.
I have tried to select count of all records which have to be remapped but I dont know exactly if my query is correct.
Here are those two tables:
select * from temp_1;
select * from temp_2;
Here is the select with count:
SELECT count(*) FROM temp_1 T1
WHERE EXISTS (SELECT 1 FROM temp_2 T2 WHERE T2.a = T1.a
and not exists (select 1 from temp_1 T1b where T2.b = T1b.a));
Sample data:
Table 1:
1, 2, 3, 4, 5, 40, 50
Table 2:
1-11, 2-22, 3-33, 4-40, 5-50
Result Table 1 after remapping:
11, 22, 33, 4, 5, 40, 50 remaining problem values
These bold marked values are the problem values if you understand me.

So, you have table 1 with column A that contains values that may also appear as new values from the re-mapping. The only solution is to use a temporary table into which you deploy the new mapping and, once you are done, copy the new mapping onto table 1.

This is not an answer - posting as one so the query can be formatted.
You may want to check to see if the PK constraint is deferrable. For example, you could run the query below. '......' means your table name, in single quotes (and in ALL CAPS). If the tables aren't yours, query ALL_CONSTRAINTS instead of USER_CONSTRAINTS. If you are lucky, the constraint is deferrable. If not we can think about other solutions. Good luck!
select constraint_name, deferrable, deferred
from user_constraints
where constraint_type = 'P'
and table_name = '.....'

Related

How to exclude a column out of multiple in select query in SQL Server?

I have 3 tables out of which one is containing two foreign keys for the primary keys of the corresponding tables. Now I want to run a query which will fetch data from these tables and will store the result-set in a new table with only one primary key of each.
Tab 1: CUSTOMER (cust_id, col2, col3.....)
Tab 2: PRODUCT (prod-id, col2, col3.....)
Tab 3: SALES (s_id, cust_id,prod_id, col2, col3.....)
Now, I want result-set to be stored in a new table "RES" containing one 'cust_id', one 'prod_id' along with rest columns rather than those of two columns.
Please help.........
Thank you :)
I tried like this:
select *
into RES
from customer c
inner join sales s on s.cust_id = c.cust_id
where c.cust_id in (select cust_id
from sales
group by cust_id
having count(cust_id) >= 2)
order by s.cust_id;
but I get this error:
Msg 2705, Level 16, State 3, Line 1
Column names in each table must be unique. Column name 'cust_id' in table 'RES' is specified more than once.
Msg 2705, Level 16, State 3, Line 1 Column names in each table must be
unique. Column name 'cust_id' in table 'RES' is specified more than
once.
You are getting this error because you are inserting all the columns of tables customer and sales into RES, where custid column is present in both the tables.
Using * for insert is not a good practice. Instead of this you can change your query like following.
INSERT INTO RES(COL1,COL2.....COLN)
SELECT COL1, COL2, ........
FROM
<QUERY>
Even you are using SELECT .. INTO, in this case also you select explicit columns.

union table, change serial primary key, postgresql

Postgresql:
I have two tables 'abc' and 'xyz' in postgresql. Both tables have same 'id' columns which type is 'serial primary key;'.
abc table id column values are 1,2,3 and also xyz id column containing same values 1,2,3,4
I want to union both tables with 'union all' constraint. But I want to change 'xyz' id column values to next value of 'abc' id column last value as 1,2,3,4,5,6,7
select id from abc
union all
select id from xyz
|id|
1
2
3
1
2
3
4
my wanted resuls as
|id|
1
2
3
4
5
6
7
BETTER - Thanks to #CaiusJard
This should do it for you
select id FROM abc
UNION ALL select x.id + a.maxid FROM xyz x,
(SELECT MAX(id) as maxid from abc) a
ORDER BY id
For anyone who's doing something like this:
I had a similar problem to this, I had table A and table B which had two different serials. My solution was to create a new table C which was identical to table B except it had an "oldid" column, and the id column was set to use the same sequence as table A. I then inserted all the data from table B into table C (putting the id in the oldid field). Once I fixed the refernces to point to from the oldid to the (new)id I was able to drop the oldid column.
In my case I needed to fix the old relations, and needed it to remain unique in the future (but I don't care that the ids from table A HAVE to all be before those from table C). Depending on what your trying to accomplish, this approach may be useful.
If anyone is going to use this approach, strictly speaking, there should be a trigger to prevent someone from manually setting an id in one table to match another. You should also alter the sequence to be owned by NONE so it's not dropped with table A, if table A is ever dropped.

Insert data from one table to other using select statement and avoid duplicate data

Database: Oracle
I want to insert data from table 1 to table 2 but the catch is, primary key of table 2 is the combination of first 4 letters and last 4 numbers of the primary key of table 1.
For example:
Table 1 - primary key : abcd12349887/abcd22339887/abcder019987
In this case even if the primary key of table 1 is different, but when I extract the 1st 4 and last 4 chars, the output will be same abcd9887
So, when I use select to insert data, I get error of duplicate PK in table 2.
What I want is if the data of the PK is already present then don't add that record.
Here's my complete stored procedure:
INSERT INTO CPIPRODUCTFAMILIE
(productfamilieid, rapport, mesh, mesh_uitbreiding, productlabelid)
(SELECT DISTINCT (CONCAT(SUBSTR(p.productnummer,1,4),SUBSTR(p.productnummer,8,4)))
productnummer,
ps.rapport, ps.mesh, ps.mesh_uitbreiding, ps.productlabelid
FROM productspecificatie ps, productgroep pg,
product p left join cpiproductfamilie cpf
on (CONCAT(SUBSTR(p.productnummer,1,4),SUBSTR(p.productnummer,8,4))) = cpf.productfamilieid
WHERE p.productnummer = ps.productnummer
AND p.productgroepid = pg.productgroepid
AND cpf.productfamilieid IS NULL
AND pg.productietype = 'P'
**AND p.ROWID IN (SELECT MAX(ROWID) FROM product
GROUP BY (CONCAT(SUBSTR(productnummer,1,4),SUBSTR(productnummer,8,4))))**
AND (CONCAT(SUBSTR(p.productnummer,1,2),SUBSTR(p.productnummer,8,4))) not in
(select productfamilieid from cpiproductfamilie));
The highlighted section seems to be wrong, and because of this the data is not picking up.
Please help
Try using this.
p.productnummer IN (SELECT MAX(productnummer) FROM product
GROUP BY (CONCAT(SUBSTR(productnummer,1,4),SUBSTR(productnummer,8,4))))

Update a table based on a results of a group by

Update a table based on a results of a group by
I've got a tricky update problem I'm trying to solve. There are two tables that contain the same three columns plus additional varied columns, looking like this:
Table1 {pers_id, loc_id, pos, ... }
Table2 {pers_id, loc_id, pos, ... }
None of the fields are unique. The first two fields collectively identify the records in a table (or tables) as belonging to the same entity. Table1 could have 15 records belonging to an entity, and table2 could have 4 records belonging to the same entity. The third column 'pos' is an index from 0 to whatever, and this is the column that I'm trying to update.
In Table1 and in Table2, the pos column begins at 0, and increments based on user selection, so that in the example (15 records in table1 and 4 records in table2), table1 contains 'pos' values of 0 - 14, and Table2 contains 'pos' values of 0-3.
I want to increment the pos field in Table1 with the results of the count of similar entities in Table2. This is the sql statement that correctly gives me the results from table2:
select table2.pers_id, table2.loc_id, count(*) as pos_increment from table2 group by table2.pers_id, table2.loc_id;
The end result of the update, in the example (15 records in table1 and 4 records in table2), would be all records in Table1 of the same entity being incremented by 4 (the result of the specific entity group by). 0 would be changed to 4, 15 to 19, etc.
Is this achievable in a single statement?
Since you only need to increment the pos field the solution is really simple:
update table1 t1
set t1.pos = t1.pos +
(select count(1)
from table2 t2
where t2.pers_id = t1.pers_id
and t2.loc_id = t1.loc_id)
Yes, this is possible, you can use MERGE for some of these upadtes and there are ways to relate values between the update and the subselect. I have done this in the past, but it's tricky and I don't have an existing example.
You can find several examples on this site, some for Oracle and some for other database that will awork with slight modifications.

SQL Server : show foreign key constraints tied to a single record

This probably is a bit complicated but is there anyway or already a script out there that could show you all foreign key constraints tied to a single table row.
What I mean by this is say you have the following DB structure:
TABLE 1
column a
column b
TABLE 2
column c
column d (foreign key constraint to 1.a)
TABLE 3
column e
column f (foreign key constraint to 2.c)
TABLE 4
column g (foreign key constraint to 3.e)
column h
Then, you have 2 rows in Table 1. One of the rows is constrained through table 2, then further to table 3, BUT not further to table 4 (IDs tied throughout tables 1-3).
I would like to simply query one of the rows in Table 1 and have it tell me that for that row there are ties that go to Table 2, and then those rows have ties to Table 3. Using this 'query' on the second row in Table 1 would simply just return nothing as there are no foreign keys that are tying that row down.
Something like this would be immensely useful when it comes to tracking down what tables/rows are currently using a particular starting row.
Thanks!
I think what you're looking for can be accomplished by:
SELECT a, t2=COUNT(d), t3 = COUNT(f), t4 = COUNT(g)
FROM [1] LEFT JOIN [2] ON 1.a=2.d
LEFT JOIN [3] ON 2.c = 3.f
LEFT JOIN [4] ON 4.g = 3.e