I'm trying to update an table with data from another table (using PostgreSQL). My table is something like:
+-------------------+-------------------+-----------------------+
| id_location | user_location | social_sec_number |
+-------------------+-------------------+-----------------------+
| 00000000001 | Jason (null) | 812.539.037 |
+-------------------+-------------------+-----------------------+
| 00000000002 | Jennifer (null) | 066.307.382 |
+-------------------+-------------------+-----------------------+
| 00000000003 | Albert (null) | 560.732.535 |
+-------------------+-------------------+-----------------------+
And I want Into this:
+-------------------+---------------------------+-----------------------+
| id_location | user_location | social_sec_number |
+-------------------+---------------------------+-----------------------+
| 00000000001 | Jason (812.539.037) | 812.539.037 |
+-------------------+---------------------------+-----------------------+
| 00000000002 | Jennifer (066.307.382) | 066.307.382 |
+-------------------+---------------------------+-----------------------+
| 00000000003 | Albert (560.732.535) | 560.732.535 |
+-------------------+---------------------------+-----------------------+
Columns id_location and user_location are in the same table TableLocation, but social_sec_number are in another table.
My code trying update them (this code does not reflect what was shown in the examples of tables):
WITH tb_cpf
AS (
SELECT doc.nr_documento_identificacao
FROM core.tb_usuario_localizacao ul
INNER JOIN core.tb_localizacao l ON ul.id_localizacao = l.id_localizacao
INNER JOIN client.tb_pess_doc_identificacao doc ON ul.id_usuario = doc.id_pessoa
WHERE l.ds_localizacao ilike '%(null)%'
AND doc.cd_tp_documento_identificacao = 'CPF'
)
UPDATE core.tb_localizacao AS l
SET l.ds_localizacao = REPLACE(l.ds_localizacao, '(null)', tb_cpf)
WHERE l.id_localizacao IN (
SELECT l.id_localizacao
FROM core.tb_usuario_localizacao ul
INNER JOIN core.tb_localizacao l ON ul.id_localizacao = l.id_localizacao
INNER JOIN client.tb_pess_doc_identificacao doc ON ul.id_usuario = doc.id_pessoa
WHERE l.ds_localizacao ilike '%(null)%'
AND doc.cd_tp_documento_identificacao = 'CPF'
)
AND tb_pess_doc_identificacao.id_pessoa = tb_usuario_localizacao.id_usuario
AND tb_usuario_localizacao.id_localizacao = tb_localizacao.id_localizacao;
And I receive this ugly error:
ERROR: column "tb_cpf" does not exist
LINE 11: ... of l.ds_localizacao = REPLACE (l.ds_localization, '(null)', tb_cpf)
^
********** Error **********
ERROR: column "tb_cpf" does not exist
SQL state: 42703
Character: 433
That way, it is possible that each record with "null" is replaced by social security (for example) on every table?
You're misunderstanding with clause usage. Think of it like a view or like a subquery. It works exactly like a memory table. You have to expose all columns you're gonna use.
But, why are you complicating it so much? Why don't you do something as simple as this?
update mytable m1
set m1.mycolumn = replace( m1.mycolumn,
'(null)',
(
select mycolumn2
from mytable2 m2
where m2.id = m1.id
)
)
where m1.mycolumn like '%(null)'
Or, if you really want to use with (for performance issues):
with t1 as
(select t.id,
t.mycolumn
from mytable
)
update mytable2 t2
set t2.mycolumn = replace (t2.mycolumn, '(null)', t1.mycolumn)
where t2.id = t1.id
and t2.mycolumn like '%(null)'
The tb_cpf from the CTE works like any other relation in your main UPDATE statement. You are missing a column identifier, so if you add .nr_documento_identificacao to tb_cpf then the update should work:
WITH tp_cpf AS (
...
)
UPDATE core.tb_localizacao AS l
SET l.ds_localizacao = REPLACE(l.ds_localizacao, 'null', tb_cpf.nr_documento_identificacao)
WHERE ...
Related
I have a table containing pairs for matches, and the table looks like this:
|pairing_id|player1_id|player2_id|number_of_round|
| 132 | Thomas | Brian | 1 |
I try to write an sql query, which shows me all the redundant pairs, so the pairing is the same if the 2 player names are the same, but for the second time, Brian is player1 and Thomas is the player2.
So this 2 matchups are considered the same pairs, as the player names are the same:
|pairing_id|player1_id|player2_id|number_of_round|
| 132 | Thomas | Brian | 1 |
| 458 | Brian | Thomas | 4 |
I need to find all the redundant pairings in the table, but sadly I dont know how to query for this.
Can be done with EXISTS
select t1.pairing_id, t1.player1_id, t1.player2_id, t1.number_of_round
from myTable t1
where exists (select null
from myTable t2
where t2.player1_id = t1.player2_id and t2.player2_id = t1.player1_id)
order by case when t1.player1_id > t1.player2_id then t1.player2_id else t1.player1_id end
You can do it with exists:
select t.* from tablename t
where exists (
select 1 from tablename
where pairing_id <> t.pairing_id and player1_id = t.player2_id and player2_id = t.player1_id
)
I have a table with md5 sums for files and use the following query to find the files which exist in one hashing-run and not in the other (oldt vs newt):
SELECT *
FROM md5_sums as oldt
WHERE NOT EXISTS (SELECT *
FROM md5_sums as newt
WHERE oldt.file = newt.file
and oldt.relpath = newt.relpath
and newt.starttime = 234)
and oldt.starttime = 123
now I want to put a flag in an extra column with an update clause, like
update md5_sums
set only_in_old = 'X'
where
and there I want a reference to the upper query as subquery, but i cannot find a proper way. Is there a possibility to use the results from the upper query for the where clause from the update-query?
(I added now some Table Screenshots with simple Table Data)
Table Description
Table Data before UPDATE
desired Table Data after UPDATE
SQLite does not support aliasing the updated table.
In your case you don't need that.
You can use the table's name md5_sums inside the subquery since you aliased the table of the SELECT statement as newt.
UPDATE md5_sums
SET only_in_old = 'X'
WHERE NOT EXISTS (
SELECT 1 FROM md5_sums AS newt
WHERE md5_sums.file = newt.file
AND md5_sums.relpath = newt.relpath
AND newt.starttime = 234
)
AND starttime = 123
See the demo.
Results:
| file | relpath | starttime | only_in_old |
| ------- | -------- | --------- | ----------- |
| abc.txt | /var/tmp | 123 | |
| abc.txt | /var/tmp | 234 | |
| def.txt | /tmp | 123 | X |
| xyz.txt | /tmp | 234 | |
I hope this helps you in converting the select statement into an update statement,
UPDATE md5_sums
SET only_in_old = 'X'
WHERE NOT EXISTS (SELECT *
FROM md5_sums newt
WHERE file = newt.file
and relpath = newt.relpath
and newt.starttime = 1551085649.7764235)
and starttime = 1551085580.009046
this is my first entry, so please excuse me for any mistakes I might make writing this Post.
I have an oracle database schema full of Table Views. I want to use the "TEXT_VC" column in the "all_views" table to get a list of the source table names.
This is my statement so far:
SELECT view_name, text_vc, REGEXP_SUBSTR(TEXT_VC,'from (.+?) ') AS source_table
FROM all_views
WHERE owner = 'OWNER';
I still have a view problems with this regex.
First of all, I am getting "from table_name" as a result. I don't want to get "from" in my result set.
Secondly, the column TEXT_VC basically displays the SQL behind the view. So in some cases I don't get any results, because there are line breaks. I tried working with \n and \r but I am not able to generate the result I want.
Can anyone please help me?
select * from all_dependencies
Demo
create table mytable_1 (i int);
create table mytable_2 (i int);
create view myview
as
select count(*) as cnt
from mytable_1 t1
join mytable_2 t2
on t2.i = t1.i
;
select *
from all_dependencies
where owner = 'DMARKOVITZ'
and name = 'MYVIEW'
;
+------------+--------+------+------------------+-----------------+-----------------+----------------------+-----------------+
| OWNER | NAME | TYPE | REFERENCED_OWNER | REFERENCED_NAME | REFERENCED_TYPE | REFERENCED_LINK_NAME | DEPENDENCY_TYPE |
+------------+--------+------+------------------+-----------------+-----------------+----------------------+-----------------+
| DMARKOVITZ | MYVIEW | VIEW | DMARKOVITZ | MYTABLE_1 | TABLE | (null) | HARD |
| DMARKOVITZ | MYVIEW | VIEW | DMARKOVITZ | MYTABLE_2 | TABLE | (null) | HARD |
+------------+--------+------+------------------+-----------------+-----------------+----------------------+-----------------+
How would I go about updating a table by using another table so it puts in the new data and if it doesnt match on an id it adds the new id and the data with it. My original table i much bigger than the new table that will update it. and the new table has a few ids that aren't in the old table but need to be added.
for example I have:
Table being updated-
+-------------------+
| Original Table |
+-------------------+
| ID | Initials |
|------+------------|
| 1 | ABC |
| 2 | DEF |
| 3 | GHI |
and...
the table I'm pulling data from to update the other table-
+-------------------+
| New Table |
+-------------------+
| ID | Initials |
|------+------------|
| 1 | XZY |
| 2 | QRS |
| 3 | GHI |
| 4 | ABC |
then I want my Original table to get its values that match up to be updated by the new table if they have changed, and add any new ID rows if they aren't in the original table so in this example it would look like the New Table.
+-------------------+
| Original Table |
+-------------------+
| ID | Initials |
|------+------------|
| 1 | XZY |
| 2 | QRS |
| 3 | GHI |
| 4 | ABC |
You can use MERGE statement to put this UPSERT operation in one statement but there are issues with merge statement I would split it into two Statements, UPDATE and INSERT
UPDATE
UPDATE O
SET O.Initials = N.Initials
FROM Original_Table O INNER JOIN New_Table N
ON O.ID = N.ID
INSERT
INSERT INTO Original_Table (ID , Initials)
SELECT ID , Initials
FROM New_Table
WHERE NOT EXISTS ( SELECT 1
FROM Original_Table
WHERE ID = Original_Table.ID)
Important Note
Reason why I suggested to avoid using merge statement read this article Use Caution with SQL Server's MERGE Statement by Aaron Bertrand
You need to use the MERGE statement for this:
MERGE original_table AS Target
USING updated_table as Source
ON original_table.id = updated_table.id
WHEN MATCHED THEN UPDATE SET Target.Initials = Source.Initials
WHEN NOT MATCHED THEN INSERT(id, Initials) VALUES(Source.id, Source.Initials);
You have not specified, what happens in case the valuesin original table are not found in the updated one. But, just in case, you can add this to remove them from original table:
WHEN NOT MATCHED BY SOURCE
THEN DELETE
if you can use loop in PHP and go through all tables and copy one by one to another table.
another option
DECLARE #COUT INT
SET #COUT = SELECT COUNT(*) FROM New_Table
WHILE (true)
BEGIN
IF #COUT = 0
BREAK;
SET #COUT = #COUT - 1
DECLARE #id INT
DECLARE #ini VARCHAR(20)
SET #id = (SELECT id FROM New_Table);
SET #ini = (SELECT Initials FROM New_Table);
IF (SELECT COUNT(*) FROM Original_Table WHERE id=#id ) > 0
UPDATE SET ID = #id,Initials = #ini FROM Original_Table WHERE id = #id;
insert into Original_Table values(#id,#ini);
END
GO
I have a complex SQL statement that I need to match up two table based on a join. The the intial part of the complex query has a location number that is stored in a table as a Smallint and the second table has the Store number stored as a CHAR(4). I have been able to cast the smallint to a char(4) like this:
CAST(STR_NBR AS CHAR(4)) AND LOCN_NBR
The issue is that because the Smallint suppresses the leading '0' the join returns null values from the right hand side of the LEFT OUTER JOIN.
Example
Table set A(Smallint) Table Set B (Char(4))
| 96 | | 096 |
| 97 | | 097 |
| 99 | | 099 |
| 100 | <- These return -> | 100 |
| 101 | <- These return -> | 101 |
| 102 | <- These return -> | 102 |
I need to add make it so that they all return, but since it is in a join statement how do you append a zero to the beginning and in certain conditions and not in others?
SELECT RIGHT('0000' || STR_NBR, 4)
FROM TABLE_A
Casting Table B's CHAR to tinyint would work as well:
SELECT ...
FROM TABLE_A A
JOIN TABLE_B B
ON A.num = CAST(B.txt AS TINYINT)
Try LPAD function:
LPAD(col,3,'0' )
I was able to successfully match it out to obtain a 3 digit location number at all times by doing the following:
STR_NBR was originally defined as a SmallINT(2)
LOCN_NO was originally defined as a Char(4)
SELECT ...
FROM TABLE_A AS A
JOIN TABLE_B AS B
ON CAST(SUBSTR(DIGITS(A.STR_NBR),3,3)AS CHAR(4)) = B.LOCN_NO