Updating a column by counting data from another table - postgresql

I have two tables let’s say A & B and would like to count the results of column2 in table B by comparing them to table A column2 and update them in table A column1.
I am using the script shown here, but it's taking a really long time so I'd appreciate it if somebody could provide an alternative / better and faster option/script
UPDATE tableA
SET tableA.column1 = (SELECT COUNT(*)
FROM tableB
WHERE tableA.column2 = tableB.column2)

Use the proprietary UPDATE ... FROM to perform a join that can be something else than a nested loop:
UPDATE tableA SET tableA.column1 = tbc.count
FROM (SELECT column2,
count(*) AS count
FROM tableB
GROUP BY column2) AS tbc
WHERE tableA.column2 = tbc.column2;

Related

multiple sequence update postgres

I have a table, on which I have added a new column nxvl.
I need to do something like this
UPDATE table1
SET nxvl = nexval('my_sequence_1')
from table2
where table1.col_id = table2.id and table2.val_col=1
order by table1.date
UPDATE table1
SET nxvl = nexval('my_sequence_2')
from table2
where table1.col_id = table2.id and table2.val_col=2
order by table1.date
Postgres doesn't allow order by on update
It has around 100,000 rows.
Can it be done with Update command. Right now there are only 2 values in val_col ie 1 & 2
Since it's a one time thing, I don't mind doing it with functions and looping through each row and update.
For knowledge wondering if there's a better way of achieving it.
Using Postgres 12.2
You can set the order and fetch the associated sequence value in a subquery, then update table (without even considering the update order)
UPDATE table1
SET nxvl = a.seq
FROM
( select table1.id, nexval('my_sequence_1') seq
from table1
join table2
on table1.col_id = table2.id
and table2.val_col=1
order by table1.date
) a
WHERE table1.id = a.id;

Updating with Nested Select Statements

I have a table that holds 3 fields of data: Acct#, YMCode, and EmployeeID. The YMCode is an Int that is formatted 201308, 201307, etc. For each Acct#, I need to select the EmployeedID used for the YMCode 201308 and then update all of the other YMCodes for the Acct# to the EmployeedID used in 201308.
so for each customer account in the table...
Update MyTable
Set EmployeeID = EmployeeID used in YMCode 201308
Having a hard time with it.
Put it in a transaction and look at the results before committing, but I think this is what you want:
UPDATE b
SET EmployeeID = a.EmployeeID
FROM MyTable a
INNER JOIN MyTable b
ON a.[Acct#] = b.[Acct#]
where a.YMCode =
(SELECT MAX(YMCode) from MyTable)
To get max YMCode, just add select statement at the end.

T-SQL Need help to optimize table value function

I need help to optmize the SQL logic in one of my functions. Please, note that I am not able to use store procedure.
Here is my table. It will be initialized using #MainTable that contains a lot of records.
DECLARE TABLE #ResultTable
(
ResultValue INT
)
These are tables that stores some parameters - they can be emty too.
DECLARE TABLE #ParameterOne (ParameterOne INT)
DECLARE TABLE #ParameterTwo (ParameterOne NVARCHAR(100))
...
DECLARE TABLE #ParameterN(ParameterN TINYINT)
Now, I need to join a lot of tables to my #MainTable in order to select from it only some of its records.
The selected records depend on the information stored in the parameters table.
So, my current solution is:
INSERT INTO ResultTable(ResultValue)
SELECT ResultValue
FROM MainTable M
INNER JOIN #MainOne MO
ON M.ID=MO.ID
....
INNER JOIN #MainN MN
ON M.IDN=MN.ID
WHERE (EXISTS (SELECT 1 FROM #ParameterOne WHERE ParameterOne=MO.ID) OR NOT EXISTS (SELECT 1 FROM #ParameterOne))
AND
...
AND
(EXISTS (SELECT 1 FROM #ParameterN WHERE ParameterN=MN.Name) OR NOT EXISTS (SELECT 1 FROM #ParameterN ))
So, the idea is to add the records only if they match the current criteria from the parameters tables.
Because I am not able to use procedure to build dynamic query I am using the WHERE clause with combinations of EXISTS and NOT EXISTS for each parameter table.
The problem is that it works slower when I am adding more and more parameters table. Is there an other way to do this without using a lot of IF/ELSE statements checking what parameter table has records - it will make the function a lot bigger and difficult for read.
And ideas and advices are welcomed.
Good question.
Try the following one:
INSERT INTO ResultTable(ResultValue)
SELECT ResultValue
FROM MainTable M
INNER JOIN (SELECT * FROM #MainOne WHERE (EXISTS (SELECT 1 FROM #ParameterOne WHERE ParameterOne=#MainOne.ID) OR NOT EXISTS (SELECT 1 FROM #ParameterOne))) MO
ON M.ID=MO.ID
....
INNER JOIN (SELECT * FROM #MainN WHERE (EXISTS (SELECT 1 FROM #ParameterN WHERE ParameterOne=#MainN.Name OR NOT EXISTS (SELECT 1 FROM #ParameterN))) MO
ON M.IDN=MN.ID
Advantages:
Result of the JOIN is more quickly, because it does not process all data (it is already filtered)
It looks more simple for adjusting

How to loop through a Table, find a value and insert if exists?

I've two table:
Table A
ID Field1 ....
Table B
ID Field2 Field3 ...
I would like to LOOP through table B and if a a record with same ID exits in table A, add the value Field2 and Field3 in Table A.
I don't know how to do in T-SQL!
Using a loop construction is not necessary for this update, you can solve it in a neater way by using set operations. If I understand the question correctly you want to UPDATE table A with the values from table B. Use a query like this:
UPDATE TableA
SET TableA.Field2 = TableB.Field2, TableA.Field3 = TableB.Field3
FROM TableB
WHERE TableA.ID = TableB.ID
You might wanna do an extra check in this query to see what the values in field 2 and 3 in table A are before replacing them.
(To test first what the results of this query will be, build a SELECT query from the UPDATE query above!)
SELECT CASE
WHEN TableA.ID IS NULL THEN TableB.Field2
ELSE TableB.Field3
END as FieldX
FROM TableB LEFT OUTER JOIN TableA
ON TableA.ID = TableB.ID
Probably you can do it simply like this:
select tab2.id, (tab2.field2 + tab2.field3) as sumfield
from tab2 join tab1 on tab2.id = tab1.id
OR
select tab2.id, (tab2.field2 + tab2.field3) as sumfield
from tab2
join
(select distinct id from tab1) tab1
on tab2.id = tab1.id

Bulk update a column in Oracle 11G

I have two tables say Table1 and Table2 that contains the following column with which I should join and perform an update a column of Table1 with the value of the same column present in Table2.
Columns for Join condition:
Table1.mem_ssn and Table2.ins_ssn
Table1.sys_id and Table2.sys_id
Table1.grp_id and Table2.grp_id
Column to update:
Table1.dtofhire=Table2.dtofhire
I need a way to bulk update (using single update query without looping) the above mentioned column in Oracle 11G.
Table1 does not contain any key constraint specified since it will be used as a staging table for Data upload.
Please help me out to update the same.
You can use the MERGE statement.
It should look something like this:
MERGE INTO table1 D
USING (SELECT * FROM table2 ) S
ON (D.mem_ssn = S.ins_ssn and D.sys_id = S.sys_id and D.grp_id=S.grp_id)
WHEN MATCHED THEN
UPDATE SET D.dtofhire=S.dtofhire;
UPDATE:
Since you have more than one row in table2 with the same (ins_ssn,sys_id,grp_id) and you want the max dtofhire, you should change the query in the using clause:
MERGE INTO table1 D
USING (SELECT ins_ssn, sys_id, grp_id, max(dtofhire) m_dtofhire
FROM table2
GROUP BY ins_ssn,sys_id,grp_id) S
ON (D.mem_ssn = S.ins_ssn and D.sys_id = S.sys_id and D.grp_id=S.grp_id)
WHEN MATCHED THEN
UPDATE SET D.dtofhire=S.m_dtofhire;
The query that I used to arrive the functionality is seen below
UPDATE table1 T2
SET dtofhire = (SELECT Max(dtofhire) AS dtofhire
FROM table2 T1
WHERE T2.mem_ssn = T1.ins_ssn
AND T2.sys_id = T1.sys_id
AND T2.grp_id = T1.grp_id
GROUP BY ins_ssn,
sys_id,
grp_id)
WHERE ( mem_ssn, sys_id, grp_id ) IN (SELECT ins_ssn,
sys_id,
grp_id
FROM table2 );