SQL Server Update from group by - sql

I need to update the column of a temp table from the count of a field from another table. I was trying to do this with the following query, but I get a syntax error.
How should I write this query?
Thanks!
UPDATE #ResultadosTest
SET PalletsReservados = COUNT(pe.paen_numero)
FROM #ResultadosTest RT, dba.spro_palletencab pe
WHERE pe.pate_tempor = RT.pate_tempor
AND pe.expo_codigo = RT.expo_codigo
AND pe.WeekLinId = RT.WeekLinId
AND pe.plde_codigo = RT.plde_codigo
AND pe.paen_estado = 1
AND ISNULL(pe.LoteCargaId, 0) <> 0
AND ISNULL(pe.PREMOPID, 0) <> 0
GROUP BY
pe.pate_tempor, pe.expo_codigo, pe.WeekLinId, pe.plde_codigo
The error is:
Line 10, Incorrect syntax near the keyword 'GROUP' (42000,156)

You can't directly use an aggregate function at update statement. Instead you can you a derived table
Update #ResultadosTest
SET PalletsReservados = ppp.countpaen_numero
From (Select Count(pe.paen_numero) as countpaen_numero ,pe.pate_tempor,spro_palletencab,........
FROM #ResultadosTest RT,dba.spro_palletencab pe
Where pe.pate_tempor=RT.pate_tempor
AND pe.expo_codigo=RT.expo_codigo
AND pe.WeekLinId=RT.WeekLinId
AND pe.plde_codigo=RT.plde_codigo
AND pe.paen_estado=1 AND IsNull(pe.LoteCargaId,0)<>0 AND IsNull(pe.PREMOPID,0)<>0
GROUP BY pe.pate_tempor,pe.expo_codigo,pe.WeekLinId,pe.plde_codigo ) ppp
Where ppp.pate_tempor = Field..

First group, then join
Update #ResultadosTest
SET PalletsReservados = pe.Cnt
FROM #ResultadosTest RT
JOIN (
SELECT pate_tempor, expo_codigo, WeekLinId, plde_codigo, Count(pe.paen_numero) cnt
FROM dba.spro_palletencab pe
WHERE paen_estado=1 AND IsNull(LoteCargaId,0)<>0 AND IsNull(PREMOPID,0)<>0
GROUP BY pate_tempor,expo_codigo,WeekLinId,plde_codigo
) pe ON pe.pate_tempor=RT.pate_tempor
AND pe.expo_codigo=RT.expo_codigo
AND pe.WeekLinId=RT.WeekLinId
AND pe.plde_codigo=RT.plde_codigo;

should work like:
UPDATE RT
SET PalletsReservados = pe.ctr
FROM #ResultadosTest RT
INNER JOIN
(
SELECT pate_tempor
,expo_codigo
,WeekLinId
,plde_codigo
,Count(pe.paen_numero) as ctr
FROM dba.spro_palletencab
WHERE paen_estado = 1
AND ISNULL(LoteCargaId,0) <> 0
AND ISNULL(PREMOPID,0) <> 0
GROUP BY pe.pate_tempor
,pe.expo_codigo
,pe.WeekLinId
,pe.plde_codigo
) pe
ON pe.pate_tempor = RT.pate_tempor
AND pe.expo_codigo = RT.expo_codigo
AND pe.WeekLinId = RT.WeekLinId
AND pe.plde_codigo = RT.plde_codigo

Related

UPDATE statement with JOIN in SQL Server Not Working as Expected

I'm attempting to update the LAST_INSPECTION_FW field for all records in the VEHICLES_FW table with the last JOB_DATE_FW for records with the REASON_CODE_FW = 35. However, what's happening is that once the below code is executed, it's not taking into consideration the WHERE clause. This causes all of the records to update when it should just be updating those with the REASON_CODE_FW = 35.
Is there a way to restructure this code to get it working correctly? Please help, thanks!
UPDATE VEHICLES_FW
SET VEHICLES_FW.LAST_INSPECTION_FW = JOB_HEADERS_FW.FIELD2MAX
FROM VEHICLES_FW
INNER JOIN (SELECT VEHICLE_ID_FW, MAX(JOB_DATE_FW) AS FIELD2MAX
FROM JOB_HEADERS_FW
GROUP BY VEHICLE_ID_FW) AS JOB_HEADERS_FW
ON VEHICLES_FW.VEHICLE_ID_FW = JOB_HEADERS_FW.VEHICLE_ID_FW
INNER JOIN JOB_DETAILS_FW
ON JOB_NUMBER_FW = JOB_NUMBER_FW
WHERE REASON_CODE_FW = '35'
Common Table Expressions are your friend here. SQL Server's strange UPDATE ... FROM syntax is not. EG
with JOB_HEADERS_FW_BY_VEHICLE_ID as
(
SELECT VEHICLE_ID_FW, MAX(JOB_DATE_FW) AS FIELD2MAX
FROM JOB_HEADERS_FW
GROUP BY VEHICLE_ID_FW
), q as
(
Select VEHICLES_FW.LAST_INSPECTION_FW, JOB_HEADERS_FW_BY_VEHICLE_ID.FIELD2MAX NEW_LAST_INSPECTION_FW
FROM VEHICLES_FW
INNER JOIN JOB_HEADERS_FW_BY_VEHICLE_ID
ON VEHICLES_FW.VEHICLE_ID_FW = JOB_HEADERS_FW_BY_VEHICLE_ID.VEHICLE_ID_FW
INNER JOIN JOB_DETAILS_FW
ON JOB_NUMBER_FW = JOB_NUMBER_FW
WHERE REASON_CODE_FW = '35'
)
UPDATE q set LAST_INSPECTION_FW = NEW_LAST_INSPECTION_FW
I suspect this does what you want:
update v
set last_inspection_fw = (
select max(j.job_date_fw)
from job_headers_fw j
inner join job_details_fw jd on jd.job_number_fw = j.job_number_fw
where j.vehicle_id_fw = v.vehicle_id_fw and jd.reason_code_fw = 35
)
from vehicles_fw v

ORA-00971: Missing SET keyword

I'm getting a confusing "ORA97100 missing SET keyword" error when trying to run this simple UPDATE statement.
UPDATE
(SELECT
RKAP_PROYEKSI.ID AS ID,
RKAP_PROYEKSI.TAHUN AS TAHUN,
RKAP_PROYEKSI.KODE_ANGGARAN AS KODE_ANGGARAN,
RKAP_PROYEKSI.JENIS_BIAYA AS JENIS_BIAYA,
RKAP_PROYEKSI.SUBTOTAL AS SUBTOTAL,
RKAP_PROYEKSI.TOTAL AS TOTAL,
RKAP_PROYEKSI.BELONGS_TO AS BELONGS_TO,
RKAP_PROYEKSI.NOMOR AS NOMOR,
RKAP_PROYEKSI.STATUS AS STATUS
FROM WOS.RKAP_PROYEKSI
LEFT JOIN WOS.RKAP_MASTER_KODE ON RKAP_MASTER_KODE.ID_KODE = RKAP_PROYEKSI.KODE_ANGGARAN
LEFT JOIN WOS.RKAP_USER ON RKAP_USER.BIRO = RKAP_MASTER_KODE.BIRO
WHERE TAHUN = '2018' AND RKAP_MASTER_KODE.BIRO = 'BSI') AS helper
SET helper.STATUS = 0
I've also tried to erase the "AS", but still get in error.
Any well thought to advise will be appreciated.
Thanks
You can use WITH..AS clause :
UPDATE RKAP_PROYEKSI R
SET STATUS = (
WITH RP AS
(
SELECT
RKAP_PROYEKSI.ID AS ID,
RKAP_PROYEKSI.TAHUN AS TAHUN,
RKAP_PROYEKSI.KODE_ANGGARAN AS KODE_ANGGARAN,
RKAP_PROYEKSI.JENIS_BIAYA AS JENIS_BIAYA,
RKAP_PROYEKSI.SUBTOTAL AS SUBTOTAL,
RKAP_PROYEKSI.TOTAL AS TOTAL,
RKAP_PROYEKSI.BELONGS_TO AS BELONGS_TO,
RKAP_PROYEKSI.NOMOR AS NOMOR,
RKAP_PROYEKSI.STATUS AS STATUS,
0 AS ZERO_STATUS
FROM WOS.RKAP_PROYEKSI
LEFT JOIN WOS.RKAP_MASTER_KODE ON RKAP_MASTER_KODE.ID_KODE = RKAP_PROYEKSI.KODE_ANGGARAN
LEFT JOIN WOS.RKAP_USER ON RKAP_USER.BIRO = RKAP_MASTER_KODE.BIRO
WHERE TAHUN = '2018' AND RKAP_MASTER_KODE.BIRO = 'BSI')
SELECT RP.ZERO_STATUS
FROM RP
WHERE RP.ID = R.ID
)
I think you can phrase this as:
UPDATE WOS.RKAP_PROYEKSI p
SET STATUS = 0
WHERE p.TAHUN = '2018' AND
EXISTS (SELECT 1
FROM WOS.RKAP_MASTER_KODE mk JOIN
WOS.RKAP_USER u
ON u.BIRO = mk.BIRO
WHERE mk.ID_KODE = p.KODE_ANGGARAN AND
mk.BIRO = 'BSI'
);
I don't see what RKAP_USER is being used for, but I left it in the query, just in case.

Get the sum of a count column in SQL

I have the following query
SELECT
dtc.coupon_type_company_name,
COUNT(*) * dtc.coupon_type_company_coupon_amount AS 'Total_Coupon_To_Be_Used',
dtc.coupon_type_company_coupon_months_combinable
FROM
[dbo].[coupon_type_Company_User] dtcu
JOIN
coupon_type_Company dtc ON dtcu.coupon_type_Company_ID = dtc.id
JOIN
person p ON dtcu.userID = p.userID
WHERE
coupon_type_company_coupon_is_combinable = 1
OR coupon_type_company_has_coupon = 1
AND dtc.companyID = 1081
AND p.is_active = 1
GROUP BY
dtc.coupon_type_company_name,dtc.coupon_type_company_coupon_amount,
dtc.coupon_type_company_coupon_months_combinable
This returns the following:
What I want to have however is just one column and one row that should take the SUM of my middle column (count(*)*dtc.coupon_type_company_coupon_amount).
How could I achieve this and prevent doing this in my code backend (C#)
You can wrap your query like this:
SELECT SUM(Total_Coupon_To_Be_Used) AS the_sum
FROM (
your query
) s
Use a "Table Expression", as in:
select sum(Total_Coupon_To_Be_Used) from (
SELECT dtc.coupon_type_company_name,
count(*) * dtc.coupon_type_company_coupon_amount as 'Total_Coupon_To_Be_Used',
dtc.coupon_type_company_coupon_months_combinable
FROM [dbo].[coupon_type_Company_User] dtcu
JOIN coupon_type_Company dtc ON dtcu.coupon_type_Company_ID = dtc.id
JOIN person p ON dtcu.userID = p.userID
WHERE coupon_type_company_coupon_is_combinable = 1
or coupon_type_company_has_coupon = 1
and dtc.companyID = 1081
AND p.is_active = 1
GROUP BY
dtc.coupon_type_company_name,dtc.coupon_type_company_coupon_amount,
dtc.coupon_type_company_coupon_months_combinable
) x

Merge Source Table Into Target Table using subjoins

I am new to SQLDeveloper. Please help me in correcting the merge syntax.I want to merge the data from act_sl tavle into act_sls_0 table
I am using 2 joins in From Clause.
But I am Getting Errors :
Error(13,13): PL/SQL: ORA-00969: missing ON keyword
Error(4,1): PL/SQL: SQL Statement ignored
merge into act_sls_0 using(
( select * from
(select a_0.asp, gadim.uic as ga, pmm_styleid, week, colorcode , sizecode, storenum, units_asly,retail_asly,
cost_asly ,units_asregly,retail_asregly,units_asmkdly,retail_asmkdly,units_as_pln,retail_as_pln
from act_sls
join dimension w on w.externalkey = 'W'||substr(WEEK,3,2)||'_'||substr(WEEK,5,2)
join a_0 on ( w.externalkey between startweek and endweek)
join dimension strdim on strdim.externalkey = (case when length(storenum) <= 4 then RPAD('STR-', 8 - length(storenum), '0') else 'STR-' END) || storenum
join store_info_0 str on store = strdim.uic
join dimension gadim on gadim.externalkey = decode(store_type, 'RETAIL', 'GA-01', 'ECOM', 'GA-02', '')
where trendweeks < 6)t1
join(select distinct asp, product, ga, color, sstyl_shade, pmm_styleid from aplc_1 aplc
join apc_1 apc using (asp,product,color)
where activeitem = 1 and ga!=0 and color != 0)t2
on (t1.asp = t2.asp and
t1.pmm_styleid = t2.pmm_styleid
and (case when length(t1.colorcode) <= 4 then RPAD('SHD-', 8 - length(t1.colorcode), '0') else 'SHD-' END) || t1.colorcode = t2.sstyl_shade
and t1.ga = t2.ga))src
on (trg.asp = src.asp and trg.pmm_styleid = src.pmm_styleid and trg.colorcode = src.colorcode and trg.ga = src.ga)
when matched THEN
update SET
when matched THEN
update SET
trg.UNITS_ASLY = src.UNITS_ASLY,
trg.RETAIL_ASLY = src.RETAIL_ASLY,
trg.COST_ASLY = src.COST_ASLY,
trg.UNITS_ASREGLY = src.UNITS_ASREGLY,
trg.RETAIL_ASREGLY = src.RETAIL_ASREGLY,
trg.UNITS_ASMKDLY = src.UNITS_ASMKDLY,
trg.RETAIL_ASMKDLY = src.RETAIL_ASMKDLY,
trg.UNITS_AS_PLN = src.UNITS_AS_PLN,
trg.RETAIL_AS_PLN = src.RETAIL_AS_PLN
when not matched then insert
(trg.asp,trg.ga, trg.pmm_styleid, trg.colorcode,trg.sizecode,trg.storenum,trg.week,trg.UNITS_ASLY,trg.RETAIL_ASLY ,trg.COST_ASLY , trg.UNITS_ASREGLY ,trg.RETAIL_ASREGLY ,
trg.UNITS_ASMKDLY ,trg.RETAIL_ASMKDLY ,trg.UNITS_AS_PLN ,trg.RETAIL_AS_PLN )
values
(src.asp,src.ga, src.pmm_styleid, src.colorcode,src.sizecode,src.storenum,src.week,src.UNITS_ASLY,src.RETAIL_ASLY,src.COST_ASLY,src.UNITS_ASREGLY,
src.RETAIL_ASREGLY, src.UNITS_ASMKDLY, src.RETAIL_ASMKDLY, src.UNITS_AS_PLN, src.RETAIL_AS_PLN);
The format for a merge statement is:
merge into <target_table> tgt
using <table_name or subquery> src
on (<join conditions between the target and source datasets>)
when matched then
update set ...
when not matched then
insert (...)
values (...);
Quite apart from the fact that your source subquery is incorrect (there are errors around where the t1 and t2 are; too many brackets, inappropriately trying to alias something etc), whilst you have join conditions inside your subquery, you're completely missing the ON clause for the merge itself.
You need to define the join conditions that match the data returned by your source subquery to your target table.
Now the error is : src.ga - Invalid Identifier
Although I have ga table in Trg table and src table .
merge into act_sls_0 trg using( select * from
(select a_0.asp, gadim.uic as ga, pmm_styleid, week, colorcode , sizecode, storenum, units_asly,retail_asly,
cost_asly ,units_asregly,retail_asregly,units_asmkdly,retail_asmkdly,units_as_pln,retail_as_pln
from act_sls
join dimension w on w.externalkey = 'W'||substr(WEEK,3,2)||'_'||substr(WEEK,5,2)
join a_0 on ( w.externalkey between startweek and endweek)
join dimension strdim on strdim.externalkey = (case when length(storenum) <= 4 then RPAD('STR-', 8 - length(storenum), '0') else 'STR-' END) || storenum
join store_info_0 str on store = strdim.uic
join dimension gadim on gadim.externalkey = decode(store_type, 'RETAIL', 'GA-01', 'ECOM', 'GA-02', '')
where trendweeks < 6)t1
join(select distinct asp, product, ga, color, sstyl_shade, pmm_styleid from aplc_1 aplc
join apc_1 apc using (asp,product,color)
where activeitem = 1 and ga!=0 and color != 0)t2
on (t1.asp = t2.asp and
t1.pmm_styleid = t2.pmm_styleid
and (case when length(t1.colorcode) <= 4 then RPAD('SHD-', 8 - length(t1.colorcode), '0') else 'SHD-' END) || t1.colorcode = t2.sstyl_shade
and t1.ga = t2.ga))src
on (trg.asp = src.asp and trg.pmm_styleid = src.pmm_styleid and trg.colorcode = src.colorcode and trg.ga = src.ga)
when matched THEN
update SET
trg.UNITS_ASLY = src.UNITS_ASLY,
trg.RETAIL_ASLY = src.RETAIL_ASLY,
trg.COST_ASLY = src.COST_ASLY,
trg.UNITS_ASREGLY = src.UNITS_ASREGLY,
trg.RETAIL_ASREGLY = src.RETAIL_ASREGLY,
trg.UNITS_ASMKDLY = src.UNITS_ASMKDLY,
trg.RETAIL_ASMKDLY = src.RETAIL_ASMKDLY,
trg.UNITS_AS_PLN = src.UNITS_AS_PLN,
trg.RETAIL_AS_PLN = src.RETAIL_AS_PLN
when not matched then insert
(trg.asp,trg.ga, trg.pmm_styleid, trg.colorcode,trg.sizecode,trg.storenum,trg.week,trg.UNITS_ASLY,trg.RETAIL_ASLY ,trg.COST_ASLY ,trg.UNITS_ASREGLY ,trg.RETAIL_ASREGLY ,
trg.UNITS_ASMKDLY ,trg.RETAIL_ASMKDLY ,trg.UNITS_AS_PLN ,trg.RETAIL_AS_PLN )
values
(src.asp,src.ga, src.pmm_styleid, src.colorcode,src.sizecode,src.storenum,src.week,src.UNITS_ASLY,src.RETAIL_ASLY,src.COST_ASLY,src.UNITS_ASREGLY,
src.RETAIL_ASREGLY, src.UNITS_ASMKDLY, src.RETAIL_ASMKDLY, src.UNITS_AS_PLN, src.RETAIL_AS_PLN);
commit;

Oracle vs MS SQL UPDATE using IN SELECT

This SQL works fine on MS SQL Server but produces an error "ORA-00907: missing right parenthesis".
SQL:
UPDATE DELIVERY
SET VISIBLE = 0
WHERE DELIVERY.ID
IN
(
SELECT DELIVERY.ID FROM delivery WHERE DELIVERY.VISIBLE = 1
EXCEPT
SELECT DELIVERY.ID FROM delivery LEFT JOIN inventory ON INVENTORY.DELIVERYID = DELIVERY.ID
WHERE ((DELIVERY.VISIBLE = 1) AND (INVENTORY.VISIBLE = 1)) AND (INVENTORY.INVENTORYSTATE = 3)
);
Is there a way to get this to work on Oracle or is an UPDATE using an IN with SELECT statements just conceptually wrong?
In Oracle, IN Can also work, just change the EXCEPT to MINUS in Oracle
http://www.techonthenet.com/sql/update.php
http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_10007.htm
http://docs.oracle.com/cd/E17952_01/refman-5.0-en/exists-and-not-exists-subqueries.html
An Sample Example for this will be
UPDATE DELIVERY
SET VISIBLE = 0
WHERE DELIVERY.ID
IN
(
(SELECT DELIVERY.ID FROM delivery WHERE DELIVERY.VISIBLE = 1)
MINUS
(SELECT DELIVERY.ID
FROM delivery LEFT JOIN inventory ON INVENTORY.DELIVERYID = DELIVERY.ID
WHERE (((DELIVERY.VISIBLE = 1) AND (INVENTORY.VISIBLE = 1))
AND (INVENTORY.INVENTORYSTATE = 3)))
);
I think you can modify this query so that it works in both SQL Server and Oracle:
UPDATE delivery d
SET d.visible = 0
WHERE d.visible = 1
AND NOT EXISTS ( SELECT 1 FROM inventory i
WHERE i.deliveryid = d.id
AND i.visible = 1
AND i.inventorystate = 3 )
This will update DELIVERY setting visible = 0 wherever visible = 1 but there is no corresponding record in INVENTORY with visible = 1 and inventorystate = 3.