Update a postgresql table with the results of query - postgresql

I have a postgresql table with 2 columns:
code
pharm
The code column doesn not contain unique values. There are duplicates in it. What I want is to count these values as:
SELECT code, COUNT(code) FROM TABLE GROUP BY code ORDER BY 1
And use the COUNT result from the query to assign it in the PHARM column. So the final table should look like this:
CODE PHARM
AB 3
AB 3
AB 3
CD 2
CD 2
...
I tried to experiment with the UPDATE query as:
UPDATE TABLE SET (pharm) = (SELECT COUNT(code) FROM TABLE GROUP BY code)
However this doesnt work and I am quite sure is not the right way to do it. I guess I need to build some function to do this type of update?

You can do it with a join of the table to your query:
update tablename t
set pharm = g.counter
from (
select code, count(*) counter
from tablename
group by code
) g
where g.code = t.code;
See the demo.
or:
update tablename t
set pharm = (select count(*) from tablename where code = t.code);
See the demo.
or:
update tablename t
set pharm = (select count(*) filter (where code = t.code) from tablename);
See the demo.

Related

Updating a column by counting data from another table

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;

After doing CTE Select Order By and then Update, Update results are not ordered the same (TSQL)

The code is roughly like this:
WITH cte AS
(
SELECT TOP 4 id, due_date, check
FROM table_a a
INNER JOIN table_b b ON a.linkid = b.linkid
WHERE
b.status = 1
AND due_date > GetDate()
ORDER BY due_date, id
)
UPDATE cte
SET check = 1
OUTPUT
INSERTED.id,
INSERTED.due_date
Note: the actual data has same due_date.
When I ran the SELECT statement only inside the cte, I could get the result, for ex: 1, 2, 3, 4.
But after the UPDATE statement, the updated results are: 4, 1, 2, 3
Why is this (order-change) happening?
How to keep or re-order the results back to 1,2,3,4 in this same 1 query?
In MSDN https://msdn.microsoft.com/pl-pl/library/ms177564(v=sql.110).aspx you can read that
There is no guarantee that the order in which the changes are applied
to the table and the order in which the rows are inserted into the
output table or table variable will correspond.
Thats mean you can't solve your problem with only one query. But you still can use one batch to do what you need. Because your output don't guarantee the order then you have to save it in another table and order it after update. This code will return your output values in order that you assume:
declare #outputTable table( id int, due_date date);
with cte as (
select top 4 id, due_date, check
from table_a a
inner join table_b b on a.linkid = b.linkid
where b.status = 1
and due_date > GetDate()
order by due_date, id
)
update cte
set check = 1
output inserted.id, inserted.due_date
into #outputTable;
select *
from #outputTable
order by due_date, 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.

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 );