Is there a way to use joins in update statements for DB2?
Google has really let me down.
This is roughly what I'm trying to achieve (... except obviously working ....)
Update gk.WR_VEHICLE_WARRANTY w
join gk.VGARANT_FRIST_ZUWEIS z
on z.PK_GARANT_FRIST_ZUWEIS = w.FK_GARANT_FRIST_ZUWEIS
set CURRENT = '1'
where z.GW = '1'
and z.FK_GBE is null
and z.INTERN = '0';
I solved the problem , just took out the join and did a inner select
Update gk.WR_VEHICLE_WARRANTY
set CURRENT = '1'
Where FK_GARANT_FRIST_ZUWEIS in
(select PK_GARANT_FRIST_ZUWEIS from gk.VGARANT_FRIST_ZUWEIS z
where z.GW = '1'
and z.FK_GBE is null
and z.INTERN = '0' )
Related
I have a fairly complex Stored Procedure that is joining several tables together, but I need yet another column called in from a table that is yet to be joined.
Here's the Stored Procedure as it stands:
CREATE PROCEDURE [rpt].[PlannerShipToLocations_ds1]
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql nvarchar(4000)
,#DateStart nvarchar(10) = '2015-01-01'
DECLARE #t TABLE (
[PCN] int
,[Part_Key] int
,[Customer_Address_No] int
PRIMARY KEY CLUSTERED (
[Part_Key]
,[Customer_Address_No]
,[PCN]
)
)
SET #sql =
'SELECT *
FROM OPENQUERY (PLEXRPTSVR,
''SELECT DISTINCT
s.[PCN]
,sl.[Part_Key]
,s.[Customer_Address_No]
FROM [Sales_v_Shipper_e] AS s
INNER JOIN [Sales_v_Shipper_Status_e] AS ss
ON s.[PCN] = ss.[PCN]
AND s.[Shipper_Status_Key] = ss.[Shipper_Status_Key]
INNER JOIN [Sales_v_Shipper_Line_e] AS sl
ON s.[PCN] = sl.[PCN]
AND s.[Shipper_Key] = sl.[Shipper_Key]
WHERE 1 = 1
AND ss.[Shipped] = 1
AND s.[Ship_Date] >= ''''' + #DateStart + '''''
;'')'
INSERT INTO #t
EXECUTE sp_executesql #sql
;WITH base AS (
SELECT DISTINCT u.[Last_Name] + ', ' + u.[First_Name] AS [Planner]
,c.[Customer_Code] AS [Customer Code]
,c.[Name] AS [Customer Name]
,a.[Customer_Address_Code] AS [Customer Address Code]
**/* xxx.[Country] AS [Country] */**
FROM [plx].[Part_v_Customer_Part_e] cp
INNER JOIN [plx].[Part_v_Part_e] p
ON cp.[Plexus_Customer_No] = p.[Plexus_Customer_No]
AND cp.[Part_Key] = p.[Part_Key]
INNER JOIN [plx].[Common_v_Customer_e] c
ON cp.[Plexus_Customer_No] = c.[Plexus_Customer_No]
AND cp.[Customer_No] = c.[Customer_No]
INNER JOIN [plx].[Plexus_Control_v_Plexus_User_e] u
ON p.[Plexus_Customer_No] = u.[Plexus_Customer_No]
AND p.[Planner] = u.[Plexus_User_No]
OUTER APPLY (
SELECT [Customer_Address_Code], **/*[Country]*/**
FROM [plx].[Common_v_Customer_Address_e] a
INNER JOIN #t t
ON a.[Plexus_Customer_No] = t.[PCN]
AND a.[Customer_Address_No] = t.[Customer_Address_No]
**/* INNER JOIN [plx].[Common_v_Country] xxx
ON a.[Country_Key] = xxx.[Country_Key] */**
WHERE a.[Plexus_Customer_No] = p.[Plexus_Customer_No]
AND a.[Customer_No] = c.[Customer_No]
AND t.[Part_Key] = p.[Part_Key]
AND a.[Ship_To] = 1
) a
**
/* INNER JOIN [plx].[Common_v_Country] xxx
ON a.[Country_Key] = xxx.[Country_Key] */
/*
OUTER APPLY (
SELECT [Country]
FROM [plx].[Common_v_Country] xxx
INNER JOIN #t t
ON a.[Country_Key] = xxx.[Country_Key]
WHERE a.[Plexus_Customer_No] = p.[Plexus_Customer_No]
AND a.[Customer_No] = c.[Customer_No]
AND t.[Part_Key] = p.[Part_Key]
AND a.[Ship_To] = 1
) xxx
*/**
WHERE 1 = 1
AND u.[Lockout] = 0
AND p.[Part_Status] IN ('Production', 'Production - Near EOP', 'Pre-Production')
AND cp.[Active] = 1
)
SELECT t1.[Planner]
,t1.[Customer Code]
,t1.[Customer Name]
,STUFF(
(SELECT
' | ' + t2.[Customer Address Code]
FROM base t2
WHERE t1.[Planner] = t2.[Planner]
and t1.[Customer Code] = t2.[Customer Code]
ORDER BY t2.[Customer Address Code]
FOR XML PATH(''), TYPE
).value('.','varchar(max)')
,1,3,'') AS [Customer Address Code(s)]
FROM base t1
GROUP BY t1.[Planner]
,t1.[Customer Code]
,t1.[Customer Name]
ORDER BY [Customer Code]
,[Planner]
,[Customer Address Code(s)]
END
GO
I've bolded the sections that are my best guesses about how to go about joining this additional table, I recognize that I wouldn't use all of them but I wanted to show my thoughts. To break it down:
1.) [plx].[Common_v_Customer_Address_e] a AND [plx].[Common_v_Country] xxx are the two tables I need in order to call [Country] out by name. I essentially need to add this as a column displayed on the report and eventually will need to sort on it as well (I'll probably add it to ORDER BY at the end).
2.) I'm not sure if I need to be joining [plx].[Common_v_Country] xxx within the OUTER APPLY or if it needs its own separate INNER JOIN or what. I've illustrated and commented out both here. So far everything I've tried results in "The multi-part identifier 'xxx.Country' could not be bound."
Thanks for the help.
I've tried modifying the OUTER APPLY to include the new table. I've tried creating my own new INNER JOIN. I've tried creating my own new OUTER APPLY.
I have built a PosgtreSQL request that works well in my PG client tool, but don't work when transposed for Rails.
The request that works:
SELECT
usr_drinks.optimized_all
COUNT(usr_drinks.optimized_all),
FROM
usr_seasons
INNER JOIN usr_drinks ON usr_drinks.id = usr_seasons.drink_id
INNER JOIN usr_properties ON usr_properties.id = usr_drinks.property_id
AND usr_properties.winery_id = 526
INNER JOIN msr_wineries ON msr_wineries.id = usr_properties.winery_id
INNER JOIN usr_photos ON usr_photos.season_id = usr_seasons.id
AND(usr_photos.verified_kind = 1
OR usr_photos.verified_kind = 0)
AND usr_photos.verified_at IS NOT NULL
WHERE
usr_drinks.optimized_at IS NOT NULL
AND usr_drinks.verified_at IS NULL
AND NOT EXISTS (
SELECT
NULL
FROM
msr_references
WHERE
msr_references.winery_id = msr_wineries.id
AND msr_references.verified_at IS NOT NULL)
GROUP BY
usr_drinks.optimized_all
HAVING COUNT(usr_drinks.optimized_all) > 5;
Now, In rails (I don't write the WHERE and JOIN there to clarify the request):
#record_with_minimum_drinks = Season.group("usr_drinks.optimized_all").
select("usr_drinks.optimized_all, COUNT(usr_drinks.optimized_all)").
where(where).
joins(joins).
having("COUNT(usr_drinks.optimized_all) > ?", #split_minimum_drinks).
first
But I obtain the classical error:
PG::GroupingError: ERROR: column "usr_seasons.id" must appear in the
GROUP BY clause
What did I miss ?
Thanks
ActiveRecord::FinderMethods#first adds sort by and limit to the query, which obviously will interfere with your request.
Any way to improve the performance of this store procedure?
For example combining both updates clauses in a unique statement (T-SQL).
BonosConvenio and CON_Convenio are almost 5K rows.
create table #resultados (
monto_deuda float
,Cuenta float
,Rut varchar(10)
,CodCONVENIO varchar(4)
,CONVENIO varchar(50)
,Bono varchar(15)
,MontoBono float
,ApellDeudor varchar(100)
)
INSERT INTO #resultados(Cuenta,monto_deuda,Rut,CodCONVENIO,CONVENIO,Bono,MontoBono,ApellDeudor)
select ATC_CTA_Correlativo, monto_deuda, RutDeudor, CodCONVENIO,'','',0,''
from CartaCobProgramasCONVENIO
where Nomina = #Nomina
UPDATE #resultados
SET Bono=bc.Bono,
MontoBono=bc.Monto
FROM BonosCONVENIO bc
WHERE bc.ATC_CTA_Correlativo=#resultados.Cuenta;
UPDATE #resultados
SET ApellDeudor=upper(rtrim(ltrim(Paciente.PAC_PAC_Nombre))
FROM BD_ENTI_CORPORATIVA..ATC_Cuenta Cuenta, BD_ENTI_CORPORATIVA..PAC_Paciente Paciente
WHERE Cuenta.ATC_CTA_Correlativo=#resultados.Cuenta AND Paciente.PAC_PAC_Numero = Cuenta.PAC_PAC_Numero
UPDATE #resultados
SET CONVENIO=c.CON_CON_Descripcio
FROM BD_ENTI_CORPORATIVA..CON_Convenio c
WHERE c.CON_CON_Codigo =#resultados.CodCONVENIO
SELECT * FROM #resultados ORDER BY Cuenta,Bono
End
Try this:
SELECT
ccpc.ATC_CTA_Correlativo Cuenta
, ccpc.monto_deuda
, ccpc.RutDeudor Rut
, ccpc.CodCONVENIO
, c.CON_CON_Descripcio CONVENIO
, bc.Bono
, bc.Monto MontoBono
, UPPER(RTRIM(LTRIM(Paciente.PAC_PAC_Nombre))) ApellDeudor
FROM
CartaCobProgramasCONVENIO ccpc
INNER JOIN
BonosCONVENIO bc ON
ccpc.ATC_CTA_Correlativo = bc.ATC_CTA_Correlativo
INNER JOIN
BD_ENTI_CORPORATIVA..ATC_Cuenta Cuenta ON
ccpc.ATC_CTA_Correlativo = Cuenta.ATC_CTA_Correlativo
INNER JOIN
BD_ENTI_CORPORATIVA..PAC_Paciente Paciente ON
Cuenta.PAC_PAC_Numero = Paciente.PAC_PAC_Numero
INNER JOIN
BD_ENTI_CORPORATIVA..CON_Convenio c ON
c.CON_CON_Codigo = ccpc.CodCONVENIO
WHERE Nomina = #Nomina;
If you have duplicate records because of the joins, it's because there are multiple values in the tables. Your original query (using an update) would overwrite and only show the last row's value. To work around this, you would probably want to have a GROUP BY and MIN, MAX, SUM or whatever.
I have 3 table t1, t2 and t3.
t1 has 2 column-> id1, val1
t2 -> id2, val2
t3 -> id3, val3
If id1=id2 and id2 = id3
then I need to update val1 ad val3.
But I have repeating id1 and each should have same val3
I am using
update t1
inner join t2 on t1.id1 = t2.id2
inner join t3 on t2.id2 = t3.id3
set t1.val1 = t3.val3
;
But not able to do this.
The correct syntax is:
UPDATE table_name SET column = { expression | DEFAULT } [,...]
[ FROM fromlist ]
[ WHERE condition ]
So your UPDATE statement should look as follows:
update t1 set val1 = val3
from t2 inner join t3 on t2.id2 = t3.id3
where t1.id1 = t2.id2
;
See the Redshift documentation and their comprehensive UPDATE examples.
I needed to get values from the other table, t2.val3, on Redshift. I used the following
update t1
set val1 = t2.val3
from t2 join t1 t on t.id = t2.id;
I have to re-name t1. Otherwise Redshift complains.
Per #jie solution, but expanded a bit and w/o the distraction of a table alias as a table name (heh heh):
update
my_counts
set
my_count_delta = t1.my_count - t2.my_count
from
my_counts t1 join
my_counts t2 on
t1.group_id = t2.group_id and
t2.count_dt = ( t1.count_dt - interval '1 day' )
where
t1.count_error is null
A few notes:
my_count is a running total
my_count_delta is the change from the previous day entry (-/+)
this solves the issue where running total exists, but summarial columnar data for the delta needs to be added
:heart: how pg style sql makes date add/subtraction so simple: ( t1.count_dt - interval '1 day' )
as an avid lover of LEFT JOIN i was confounded that this would not run with a left join...the error message was very clear requiring "balanced join" or was it "even join"...so i went back to the #jie version of JOIN and found that the query was incredibly fast.
My Stored Procedure takes a very long time to execute.
Can anyone suggest me what I can do to speed up the stored procedure, apart from using some good practices for writing down the queries.
I've heard about creating indices, but I'm not sure what are they.
Please suggest all the best ways to speed up my queries.
Thanks
CREATE PROCEDURE [dbo].[usp_GetAlternates]
(
#NNumber CHAR(11) ,
#pid INT ,
#pbmid INT
)
AS
BEGIN
TRUNCATE TABLE TempTherapeuticAlt
INSERT INTO TempTherapeuticAlt
SELECT NULL AS MedicationID ,
PR.ePrescribingName AS MedicationName ,
U.Strength AS MedicationStrength ,
FRM.FormName AS MedicationForm ,
PR.DEAClassificationID AS DEASchedule ,
NULL AS NDCNumber
FROM Product PR
JOIN ( SELECT MP.MarketedProductID
FROM table2 TCTSP
JOIN table3 MP ON MP.SpecificProductID = TCTSP.SpecificProductID
JOIN ( SELECT TCTSP.TherapeuticConceptTreeID
FROM table3 MP
JOIN table2 TCTSP ON MP.SpecificProductID = TCTSP.SpecificProductID
JOIN ( SELECT
PR.MarketedProductID
FROM
table4 PA
JOIN Product PR ON PA.ProductID = PR.ProductID
WHERE
PA.NDC11 = #NNumber
) PAPA ON MP.MarketedProductID = PAPA.MarketedProductID
) xxx ON TCTSP.TherapeuticConceptTreeID = xxx.TherapeuticConceptTreeID
) MPI ON PR.MarketedProductID = MPI.MarketedProductID
JOIN ( SELECT P.ProductID ,
O.Strength ,
O.Unit
FROM Product AS P
INNER JOIN table3 AS M ON P.MarketedProductID = M.MarketedProductID
INNER JOIN table5 AS S ON M.SpecificProductID = S.SpecificProductID
LEFT OUTER JOIN table6 AS O ON S.SpecificProductID = O.SpecificProductID
GROUP BY P.ProductID ,
O.Strength ,
O.Unit
) U ON PR.ProductID = U.ProductID
JOIN ( SELECT PA.ProductID ,
S.ScriptFormID ,
F.Code AS NCPDPScriptFormCode ,
S.FormName
FROM table4 AS PA
INNER JOIN table7 AS S ON PA.NCPDPScriptFormCode = S.NCPDPScriptFormCode
INNER JOIN table8 AS F ON S.FormName = F.FormName
GROUP BY PA.ProductID ,
S.ScriptFormID ,
F.Code ,
S.FormName
) FRM ON PR.ProductID = FRM.ProductID
GROUP BY PR.ePrescribingName ,
U.Strength ,
FRM.FormName ,
PR.DEAClassificationID
ORDER BY pr.ePrescribingName
SELECT LL.ProductID AS MedicationID ,
temp.MedicationName ,
temp.MedicationStrength ,
temp.MedicationForm ,
temp.DEASchedule ,
temp.NDCNumber ,
fs.[ReturnFormulary] AS FormularyStatus ,
copay.CopaTier ,
copay.FirstCopayTerm ,
copay.FlatCopayAmount ,
copay.PercentageCopay
FROM TempTherapeuticAlt temp
OUTER APPLY ( SELECT TOP 1
ProductID
FROM Product
WHERE ePrescribingName = temp.MedicationName
) AS LL
OUTER APPLY function1(#pid, LL.ProductID, #pbmid) AS fs
OUTER APPLY function2(LL.ProductID, #pbmid) AS copay
ORDER BY LL.ProductID
TRUNCATE TABLE TempTherapeuticAlt
END
GO
Here are a few:
You should have indexes for every column in a WHERE clause. See
your SQL language for how to do it.
Learn how to EXPLAIN PLAN and see what's slow.
Stored procedure languages are functional, not set based. Use JOIN and don't fall into the (n+1) query/iteration trap.
Understand how using certain functions force you to TABLE SCAN in a WHERE clause.