update multiple columns in oracle - sql

I have query :
UPDATE SDM_KARYAWAN
SET (ID_DIVISI,ID_UNIT_KERJA,ID_JABATAN) =
(
SELECT ID_DIVISI,ID_UNIT_KERJA,ID_JABATAN FROM
(
SELECT TO_CHAR(TGL_SK,'YYYYMMDD') URUT,ID_DIVISI,ID_UNIT_KERJA,ID_JABATAN
FROM SDM_KARYAWAN_JABATAN
WHERE ID_KARYAWAN = '0081005'
ORDER BY URUT DESC
)DETAIL
WHERE ROWNUM = 1
)X
WHERE ID_KARYAWAN = '0081005'
But show error like this : [Err] ORA-00933: SQL command not properly ended
Actually I can use this code :
UPDATE TABLE1 SET COL1 = 'A',COL2='B',COL3='C'...
but What i want is updating multiple columns like this :
UPDATE TABLE1 SET (COL1,COL2,COL3) (SELECT COL1,COL2,COL3 FROM TABLE2)
::EDIT::
I tried this :
SELECT A.ID_DIVISI,A.ID_UNIT_KERJA,A.ID_JABATAN,
DETAIL.ID_DIVISI X,DETAIL.ID_UNIT_KERJA Y,DETAIL.ID_JABATAN Z
FROM SDM_KARYAWAN A
INNER JOIN
(
SELECT ID_KARYAWAN, TO_CHAR(TGL_SK,'YYYYMMDD') URUT,ID_DIVISI,ID_UNIT_KERJA,ID_JABATAN
FROM SDM_KARYAWAN_JABATAN
WHERE ID_KARYAWAN = '0081005'
ORDER BY URUT DESC
)DETAIL
ON DETAIL.ID_KARYAWAN = A.ID_KARYAWAN
WHERE A.ID_KARYAWAN = DETAIL.ID_KARYAWAN
AND ROWNUM = 1
The results :
ID_DIVISI ID_UNIT_KERJA ID_JABATAN X Y Z
-----------------------------------------------------------
D1 D5000 D51000 D2 D200 D2100
Now, i want to update columns on table SDM_KARYAWAN with X,Y,Z value. what's missing from my query? pls.

This will work. Please check.
UPDATE SDM_KARYAWAN
SET (ID_DIVISI,
ID_UNIT_KERJA,
ID_JABATAN) =
(SELECT ID_DIVISI, ID_UNIT_KERJA, ID_JABATAN
FROM ( SELECT TO_CHAR (TGL_SK,'YYYYMMDD')
URUT,
ID_DIVISI,
ID_UNIT_KERJA,
ID_JABATAN
FROM SDM_KARYAWAN_JABATAN
WHERE ID_KARYAWAN = '0081005'
ORDER BY 1 DESC) DETAIL
WHERE ROWNUM = 1)
WHERE ID_KARYAWAN = '0081005'

try this:
UPDATE
(SELECT
Table1.Col1 as OLD1, Table2.Col1 as NEW1
Table1.Col2 as OLD2, Table2.Col2 as NEW2
FROM Table1
INNER JOIN Table2
-- ON Some Join Conditions
) t
SET t.OLD1 = t.NEW1,
SET t.OLD2 = t.NEW2

UPDATE <TABLENAME>
SET STATUS = CASE
WHEN WID = 1 THEN 1
WHEN WID = 2 THEN 0
WHEN WID = 3 THEN 1
END
WHERE WID IN (1,2,3);
NOTE: WHERE COMMAND IS NECESSARY...

Related

Add Value from one Row to another Row with Same Primary Key- Oracle SQL

I would like to create an update statement that adds a value from one row to the value of another row with the same ID field. Basically wherever TYPE = 'ASB' and TEMP = 'DELETE' i would like to add the AMOUNT value to the AMOUNT where TYPE = 'CON'.
This has to be done for each ID. COMBINE Field can be used as a unique identifier for each row. Perhaps a windows function? Any help is much appreciated!
Current Result:
ID TYPE AMOUNT COMBINE TEMP
0432 CMP 12828.77 0432CMP
0432 CON -2083.26 0432CON
0432 ASB 1704.03 0430ASB DELETE
Expected Result:
ID TYPE AMOUNT COMBINE TEMP
0432 CMP 12828.77 0432CMP
0432 CON -379.23 0432CON
0432 ASB 1704.03 0432ASB DELETE
You can use MERGE statement as follows:
MERGE INTO YOUR_TABLE TRG USING
(
SELECT ID, SUM(AMOUNT) AS AMOUNT
FROM YOUR_TABLE
WHERE TYPE = 'ASB' AND TEMP = 'DELETE'
GROUP BY ID
) SRC
ON ( SRC.ID = TRG.ID AND TRG.TYPE = 'CON' )
WHEN MATCHED THEN
UPDATE SET TRG.AMOUNT = TRG.AMOUNT + SRC.AMOUNT;
Cheers!!
An update should do it:
update t
set amount = amount +
(select coalesce(sum(t2.amount), 0)
from t t2
where t2.id = t.id and t2.type = 'ASB' and t2.temp = 'DELETE'
)
where t.type = 'CON' and
exists (select 1
from t t2
where t2.id = t.id and t2.type = 'ASB' and t2.temp = 'DELETE'
);

Running slow with intersect

Trying to optimize a query it is updaing the records in table A based on the INTERSECT on two data sets.
UPDATE #TableA
SET IsFlag = CASE WHEN ISNULL(RJobFlag, 0) > 0 THEN 0 ELSE 1 END
FROM #TableA AS ABC
OUTER APPLY (
SELECT 1 RJobFlag
WHERE EXISTS (
SELECT ABC.COLUMN1,ABC.COLUMN2,ABC.COLUMN3,ABC.COLUMN4,ABC.COLUMN5,ABC.COLUMN6,ABC.COLUMN7,ABC.COLUMN8,ABC.COLUMN8,ABC.COLUMN9,ABC.COLUMN10,StudentID,SubjectID
INTERSECT
SELECT XYZ.COLUMN1,XYZ.COLUMN2,XYZ.COLUMN3,XYZ.COLUMN4,XYZ.COLUMN5,XYZ.COLUMN6,XYZ.COLUMN7,XYZ.COLUMN8,XYZ.COLUMN8,XYZ.COLUMN9,XYZ.COLUMN10,StudentID,SubjectID
FROM #TableB AS XYZ
WHERE XYZ.COLUMN1 = (SELECT DISTINCT ID FROM #TableC MNOP WHERE MNOP.StudentID = ABC.StudentID)
AND StudentID = ABC.StudentID
AND SubjectID = ABC.SubjectID )
) Subquery
WHERE ABC.COLUMN1= '2'
Appretiated if you have some ideas to better optimize it.
Thanks
This might be worse never know.
UPDATE tA
SET IsFlag = COALESCE(RJobFlag, 0)
FROM #TableA tA
LEFT JOIN ( SELECT 1 RJobFlag, *
FROM #TableB tB
WHERE EXISTS ( SELECT *
FROM #TableC tC
WHERE tC.ID = tB.COLUMN1 AND tC.StudentID = tB.StudentID)
) tB
ON tA.StudentID = tB.StudentID
AND tA.SubjectID = tB.SubjectID
AND tA.COLUMN1 = tB.COLUMN1
AND tA.COLUMN2 = tB.COLUMN2
AND tA.COLUMN3 = tB.COLUMN3
AND tA.COLUMN4 = tB.COLUMN4
AND tA.COLUMN5 = tB.COLUMN5
AND tA.COLUMN6 = tB.COLUMN6
AND tA.COLUMN7 = tB.COLUMN7
AND tA.COLUMN8 = tB.COLUMN8
AND tA.COLUMN9 = tB.COLUMN9
AND tA.COLUMN10 = tB.COLUMN10
If #TableA has a bunch of records and you're using outer apply or outer join every time you update it will be slow since it has to update every single record. maybe there's a way to only update the records that have changed?

SQL Find duplicates and Update table

Im trying to update a table with a Duplicate find query, my table is made of 60k+ records and doing this over excel is kinda complicated, My table looks like this
Serial_NO
.......Determine Duplicate
1
.......................Good Record
2
.......................Good Record
3
.......................Good Record
1
.......................Duplicate
The idea of this in to only update the last or more recent duplicate entry in the table by checking the entire "Serial_NO" column and them add the 'Good Record' or 'Duplicate' in column "Determine duplicate".
thanks in advance for your help!
This assumes there is an "id" field on the table, as indicated in your comments:
update tbl x
set x.[Determine Duplicate] = 'Good Record'
where x.id = (select min(y.id) from tbl y where y.[Serial_NO] = x.[Serial_NO]);
update tbl x
set x.[Determine Duplicate] = 'Duplicate'
where x.id > (select min(y.id) from tbl y where y.[Serial_NO] = x.[Serial_NO]);
One method is with ROW_NUMBER:
WITH t AS (
SELECT
ROW_NUMBER() OVER (PARTITION BY Serial_NO ORDER BY Serial_NO) AS seq
,DetermineDuplicate
FROM dbo.YourTable
)
UPDATE t
SET DetermineDuplicate = CASE WHEN seq = 1 THEN 'Good Record' ELSE 'Duplicate' END;
After considering given comments, I think following answer will suits for your requirement.
UPDATE tbl
SET tbl.[Determine Duplicate] = tb.[Determine Duplicate]
FROM tb_src tbl
INNER JOIN
(
SELECT t1.[Serial_NO],
COALESCE(t2.isduplicate,'Good Record') AS [Determine Duplicate]
FROM
(
SELECT DISTINCT t.[Serial_NO]
FROM tb_src t
) t1
LEFT OUTER JOIN tb_src t2
ON t1.[sno] = t2.sno AND t2.isduplicate = 'Duplicate'
) tb
ON tb.[Serial_NO] = tbl.[Serial_NO]
Using above, you can go with a single query.
Please note : tb_src is the table you provide.

Nested self join, how can I fix it?

SQL can't cast those 2 tables together, does anyone know how to fix it?
select * from
(select ID from tbl_Message
WHERE ([From_User] = '38137F2C-591C-4BE6-91F8-F2C915F26066' OR [To_User] = '38137F2C-591C-4BE6-91F8-F2C915F26066')
AND [Replied_ID] = '00000000-0000-0000-0000-000000000000'
and deleted = 0 ) tbl1 inner join
(select top 1.Replied_ID as Reply_ID, Post_Date as Reply_Date from tbl_Message
where Replied_ID = tbl1.ID or ID = tbl1.ID
order by Post_Date desc) tbl2 on tbl2.Reply_ID =tbl1.ID
I am assuming you are unable to run query as structure is not correct I have updated your query try it.
select * from (
(select ID from tbl_Message
WHERE ([From_User] = '38137F2C-591C-4BE6-91F8-F2C915F26066' OR
[To_User] = '38137F2C- 591C- 4BE6-91F8-F2C915F26066')
AND [Replied_ID] = '00000000-0000-0000-0000-000000000000'
and deleted = 0 ) tbl1
inner join
(select top 1.Replied_ID as Reply_ID, Post_Date as Reply_Date from tbl_Message
where Replied_ID = tbl1.ID or ID = tbl1.ID
order by Post_Date desc) tbl2
on tbl2.Reply_ID =tbl1.ID ) as temp
if everything else you are doing is right it must work.

SELECT then UPDATE those records and then return them in STORED PROCEDURE

I want to do a SELECT to get a list of ID's, do an update based on those ID's and then return those records.
Something like this I guess, I just do not know the syntax:
SELECT WebHookLogIDs = FROM WebHookLog
WHERE Processing=0
AND Processed=0
AND Paused=0
ORDER BY FailCount ASC, WebHookLogID DESC
UPDATE WebHookLog
SET Processing = 1
WHERE WebHookLogID IN(WebHookLogIDs)
SELECT * FROM WebHookLog
WHERE WebHookLogID IN(WebHookLogIDs)
I think its better to put data in Temp table, than insert data in it
because at the last you want to return those record back , so you need to use temp table
DECLARE #Table1 TABLE (WebHookLogIDs INT)
Insert into #Table1(WebHookLogIDs )
SELECT WebHookLogIDs FROM WebHookLog
WHERE Processing=0
AND Processed=0
AND Paused=0
ORDER BY FailCount ASC, WebHookLogID DESC
UPDATE WebHookLog
SET Processing = 1
WHERE WebHookLogID IN( select WebHookLogIDs from #Table1)
SELECT * FROM WebHookLog
WHERE WebHookLogID IN(select WebHookLogIDs from #Table1)
DROP TABLE #Table1
You can't do UPDATE with SELECT with the same SQL Statement. You can however, UPDATE with JOIN instead of selecting the ID's like this:
UPDATE w1
SET w1.Processing = 1
FROM WebHookLog w1
INNER JOIN WebHookLog w2 ON w1.WebHookLogID = w2.WebHookLogID
AND w2.Processing = 0
AND w2.Processed = 0
AND w2.Paused = 0;
Later, you can do another SELECT clause.
Something like this?
UPDATE WebHookLog
SET PROCESSING = 1
WHERE WebHookLogID IN ( SELECT WebHookLogIDs = FROM WebHookLog
WHERE Processing=0
AND Processed=0
AND Paused=0)
SELECT * FROM WebHookLog
WHERE WebHookLogID IN(WebHookLogIDs)