Avoiding multiple sub queries - sql

I'm trying to update a couple of columns in a table using another record in the same table. Following is the SQL that I came up with but I'm wondering how I can avoid multiple sub queries that will return the same record. I'm working on Oracle 11gR2.
UPDATE
IFTBL E
SET
E.ATT_CREATED = (SELECT A.CREATED FROM ATT A WHERE A.ROW_ID = E.T_ACTIVITYA__RID),
E.ATT_CREATED_BY = (SELECT B.CREATED_BY FROM ATT B WHERE B.ROW_ID = E.T_ACTIVITYA__RID)
WHERE
E.IF_ROW_BATCH_NUM = BATCH_NO_IN AND E.IF_ROW_STAT = 'EXPORTED' AND E.ATT_FILE_SRC_TYPE = 'FILE';

You can use Merge.
MERGE INTO IFTBL
USING
(
SELECT CREATED,CREATED_BY,ROW_ID
FROM ATT
) A ON (A.ROW_ID = IFTBL.T_ACTIVITYA__RID)
WHEN MATCHED THEN UPDATE
SET
IFTBL.ATT_CREATED = A.CREATED,
IFTBL.ATT_CREATED_BY = A.CREATED_BY
WHERE
IFTBL.IF_ROW_BATCH_NUM = BATCH_NO_IN
AND IFTBL.IF_ROW_STAT = 'EXPORTED'
AND IFTBL.ATT_FILE_SRC_TYPE = 'FILE'

If ROW_ID is primary key in ATT and T_ACTIVITYA__RID is foreign key on IFTBL with reference to ROW_ID you may write update (select ...)
update (select E.ATT_CREATED, E.ATT_CREATED_BY
A.CREATED , A.CREATED_BY
from IFTBL E, ATT A
where E.T_ACTIVITYA__RID = A.ROW_ID(+)
AND E.IF_ROW_BATCH_NUM = BATCH_NO_IN
AND E.IF_ROW_STAT = 'EXPORTED'
AND E.ATT_FILE_SRC_TYPE = 'FILE')
SET ATT_CREATED = CREATED,
ATT_CREATED_BY = CREATED_BY ;

In addition to the other answers, you could simply do a multi-column update:
UPDATE
IFTBL E
SET
(E.ATT_CREATED, E.ATT_CREATED_BY) = (SELECT A.CREATED,
A.CREATED_BY
FROM ATT A
WHERE A.ROW_ID = E.T_ACTIVITYA__RID)
WHERE
E.IF_ROW_BATCH_NUM = BATCH_NO_IN
AND E.IF_ROW_STAT = 'EXPORTED'
AND E.ATT_FILE_SRC_TYPE = 'FILE';

Related

Update a table from another table

I have got 2 tables "animal_breeds" and "ztmp.ztmp_509810_anims_out". In "animals breed" every animal has key and breed name and percentage. Few animals might have 2 different breeds with different percentage. Now based on the animals key in "animals_breeds" i want to update "ztmp.ztmp_509810_anims_out"
i am using this code which i know is wrong
update ztmp.ztmp_509810_anims_out
set
alt_id1 = ab.breed
,alt_id2 = pcnt
,alt_id3 = ab.breed
,alt_id4 = pcnt
,alt_id5 = ab.breed
,alt_id6 = pcnt
,alt_id7 = ab.breed
,alt_id8 = pcnt
from animal_breeds ab
where ab.soc_code = ztmp_509810_anims_out.soc_code and ab.animals_key = ztmp_509810_anims_out.animals_key
and ab.soc_code = 'AUNDB';
could i use a for loop inside an update statement?
UPDATE ztmp.ztmp_509810_anims_out AS z
SET soc_code = q.soc_code,
animals_key = q.animals_key,
alt_id1 = breeds[1],
alt_id2 = pcnts[1],
alt_id3 = breeds[2],
alt_id4 = pcnts[2]
FROM (SELECT soc_code, animals_key,
array_agg(breed) breeds, array_agg(pcnt) pcnts
FROM animal_breeds
GROUP BY soc_code, animals_key
) q
WHERE z.soc_code = q.soc_code
AND z.animals_key = q.animals_key;
If there can be more than 2 breeds per animals_key, add breeds[3] and pcnts[3] and so on.

Update Query Access 2007 Group into one row

I'm playing around with access and vba. I'm struggleing to update and to group rows from tblLoadingListItems into tblLoadSummary using the query below
UPDATE tblLoadSummary INNER JOIN tblLoadingListItems ON (tblLoadSummary.salesno = tblLoadingListItems.salesno) AND (tblLoadSummary.loadnolink = tblLoadingListItems.loadnolink) SET tblLoadSummary.[Cust O/N] = [tblLoadingListItems].[Cust O/N], tblLoadSummary.traderid = [tblLoadingListItems].[traderid], tblLoadSummary.street = [tblLoadingListItems].[street], tblLoadSummary.[zone] = [tblLoadingListItems].[zone], tblLoadSummary.salesno = [tblLoadingListItems].[salesno], tblLoadSummary.[Customer Ref] = [tblLoadingListItems].[Customer Ref], tblLoadSummary.DeliveryAddress = [tblLoadingListItems].[DeliveryAddress], tblLoadSummary.Postcode = [tblLoadingListItems].[Postcode], tblLoadSummary.SumOfnoofpacks = Sum([tblLoadingListItems].[packs1]), tblLoadSummary.SumOfnoofboxes = Sum([tblLoadingListItems].[noofboxes]), tblLoadSummary.contact = [tblLoadingListItems].[contact], tblLoadSummary.telephone = [tblLoadingListItems].[telephone], tblLoadSummary.fax = [tblLoadingListItems].[fax], tblLoadSummary.email =
[tblLoadingListItems].[email], tblLoadSummary.deliverycontact = [tblLoadingListItems].[deliverycontact], tblLoadSummary.deliverytelephone = [tblLoadingListItems].[deliverytelephone], tblLoadSummary.deliveryfax = [tblLoadingListItems].[deliveryfax], tblLoadSummary.deliveryemail = [tblLoadingListItems].[deliveryemail], tblLoadSummary.acknowaddress = [tblLoadingListItems].[acknowaddress]
WHERE (((tblLoadSummary.salesno)="SM-100118") AND ((tblLoadSummary.loadnolink)=32232))
If i show datasheet view i get two rows returned, Im trying to group these rows into one.
When i try to add a GROUP BY after the WHERE i get syntax errors missing operators for all my fields.
Can you someone point me in the right direction?
I am not sure with access but starting update like this and maybe its wrong :
Update tblLoadSummary inner join...
try it like this
update t set .... from tblLoadSummary t inner join tblLoadSummary s on ...
this is the full query
UPDATE t-- tblLoadSummary
SET t.CustO/N = s.CustO/N,
t.traderid = s.traderid,
t.street = s.street,
t.zone = s.zone,
t.salesno = s.salesno,
t.CustomerRef = s.Customer Ref,
t.DeliveryAddress = s.DeliveryAddress,
t.Postcode = s.Postcode,
t.SumOfnoofpacks = Sum(s.packs1),
t.SumOfnoofboxes = Sum(s.noofboxes),
t.contact = s.contact,
t.telephone = s.telephone,
t.fax = s.fax,
t.email = s.email,
t.deliverycontact = s.deliverycontact,
t.deliverytelephone = s.deliverytelephone,
t.deliveryfax = s.deliveryfax,
t.deliveryemail = s.deliveryemail,
t.acknowaddress = s.acknowaddress
from tblLoadSummary as t
INNER JOIN tblLoadingListItems as s ON
(t.salesno = s.salesno) AND (t.loadnolink = s.loadnolink)
WHERE (((t.salesno) = "SM-100118") AND
((t.loadnolink) = 32232))

SQL UPDATE using two joined subqueries

I wrote a query that does an inner join of two subqueries. The first subquery has an alias of "SRC" and the other has an alias of "DEST". What I want to do is update some fields in the table NomineeActionLegislatorVoteDetail (part of DEST subquery) with values from the table Nominee_Committee_Vote (part of SRC subquery). It souds easy but I just cannot figure out how to do it. Does anyone have any suggestions? Any help would be appreciated.
Here is the query I wrote:
select *
from (
select ncv.*,
na.NomineeActionId,
l.LegislatorId
from ongoing..Nominee_Committee_Vote ncv
inner join azleg..NomineeAction na on
ncv.session_id = na.x_session_id and
ncv.committee_id = na.x_committee_id and
ncv.agency_id = na.x_agency_id and
ncv.position_id = na.x_position_id and
ncv.nominee_id = na.x_nominee_id and
ncv.received_date = na.x_received_date
inner join status..session s on
ncv.session_id = s.session_id
inner join azleg..Legislator l on
ncv.member_id = l.x_member_id and
s.legislature = l.LegislatureId
) SRC
inner join (
select votedetail.*
from azleg..NomineeActionLegislatorVoteDetail votedetail
inner join azleg..NomineeAction nom_action on
votedetail.NomineeActionId = nom_action.NomineeActionId
) DEST on
SRC.agency_id = DEST.x_agency_id and
SRC.position_id = DEST.x_position_id and
SRC.nominee_id = DEST.x_nominee_id and
SRC.received_date = DEST.x_received_date and
SRC.session_id = DEST.x_session_id and
SRC.committee_id = DEST.x_committee_id and
SRC.member_id = DEST.x_member_id
where SRC.NomineeActionId <> DEST.NomineeActionId
OR SRC.LegislatorId <> DEST.LegislatorId
OR SRC.Vote <> DEST.Vote
Can you insert the update in front of the sub queries
UPDATE NomineeActionLegislatorVoteDetail
SET NomineeActionLegislatorVoteDetail.COLUMNNAME = src.VALUE
--SubQueriesBelow
from
(select ncv.*, na.NomineeActionId, l.LegislatorId from ongoing..Nominee_Committee_Vote ncv
inner join azleg..NomineeAction na on
ncv.session_id = na.x_session_id and
ncv.committee_id = na.x_committee_id and
ncv.agency_id = na.x_agency_id and
ncv.position_id = na.x_position_id and
ncv.nominee_id = na.x_nominee_id and
ncv.received_date = na.x_received_date
inner join status..session s on
ncv.session_id = s.session_id
inner join azleg..Legislator l on
ncv.member_id = l.x_member_id and
s.legislature = l.LegislatureId) SRC
inner join
(select votedetail.* from azleg..NomineeActionLegislatorVoteDetail votedetail
inner join azleg..NomineeAction nom_action on
votedetail.NomineeActionId = nom_action.NomineeActionId) DEST on
SRC.agency_id = DEST.x_agency_id and
SRC.position_id = DEST.x_position_id and
SRC.nominee_id = DEST.x_nominee_id and
SRC.received_date = DEST.x_received_date and
SRC.session_id = DEST.x_session_id and
SRC.committee_id = DEST.x_committee_id and
SRC.member_id = DEST.x_member_id
where SRC.NomineeActionId <> DEST.NomineeActionId
OR SRC.LegislatorId <> DEST.LegislatorId
OR SRC.Vote <> DEST.Vote
It looks like the update is on a table in the sub query so it could be re factored to have one subquery
I've adjusted the lay-out of your query a bit to disclose better where subqueries start and end. In your DEST subquery, you join NomineeAction but you don't select any columns from it, so it only filters rows from NomineeActionLegislatorVoteDetail for which no NomineeAction exists. So really you wanna be updating and joining on columns from NomineeActionLegislatorVoteDetail exclusively. Based on that, I would write the update query like so:
update votedetail set
votedetail.SomeColumn = SomeValue,
votedetail.SomeOtherColumn = SomeOtherValue
from azleg..NomineeActionLegislatorVoteDetail votedetail
join azleg..NomineeAction nom_action on
votedetail.NomineeActionId = nom_action.NomineeActionId
join (
select ncv.*,
na.NomineeActionId,
l.LegislatorId
from ongoing..Nominee_Committee_Vote ncv
inner join azleg..NomineeAction na on
ncv.session_id = na.x_session_id and
ncv.committee_id = na.x_committee_id and
ncv.agency_id = na.x_agency_id and
ncv.position_id = na.x_position_id and
ncv.nominee_id = na.x_nominee_id and
ncv.received_date = na.x_received_date
inner join status..session s on
ncv.session_id = s.session_id
inner join azleg..Legislator l on
ncv.member_id = l.x_member_id and
s.legislature = l.LegislatureId
) SRC on
SRC.agency_id = votedetail.x_agency_id and
SRC.position_id = votedetail.x_position_id and
SRC.nominee_id = votedetail.x_nominee_id and
SRC.received_date = votedetail.x_received_date and
SRC.session_id = votedetail.x_session_id and
SRC.committee_id = votedetail.x_committee_id and
SRC.member_id = votedetail.x_member_id
where SRC.NomineeActionId <> votedetail.NomineeActionId
OR SRC.LegislatorId <> votedetail.LegislatorId
OR SRC.Vote <> votedetail.Vote

Query not updating the correct Rows

Trying to update the fact table with late coming dimension data. See Code below
UPDATE FactVehicleStock
SET
FactVehicleStock.[TOL_BidDateTime] = B.Bid_Date_and_Time,
FactVehicleStock.[TOL_AuctionDate] = B.Date_opened_for_tender,
FactVehicleStock.[TOL_OriginalLoadDate] = B.Original_Load_date,
FactVehicleStock.[TOL_ServiceHistory] = B.Service_History,
FactVehicleStock.[TOL_ReservedPrice] = B.Reserve_price,
FactVehicleStock.[TOL_BidPrice] = B.Bid_Price,
FactVehicleStock.[TOL_OriginalReservedPrice] = B.Original_Reserve_Price,
FactVehicleStock.[TOL_NoOfTimesReloaded] = B.Number_of_times_reloaded
FROM BMR_DWH.dbo.FactVehicleStock as A
INNER JOIN BMR_STAGE.dbo.STG_Traders_Online as B
ON A.StockbookNumber = B.Stock_Number
INNER JOIN BMR_DWH.[dbo].[DimDealership] as C
ON A.DEALERSHIP_KEY IN (SELECT Distinct [DEALERSHIP_KEY]
FROM BMR_DWH.[dbo].[DimDealership]
INNER JOIN [BMR_STAGE].[dbo].[STG_Traders_Online] E
ON LTRIM(RTRIM(C.MOLNUMBER)) = LTRIM(RTRIM(E.MOL_Number))
)
Try to use the right UPDATE SELECT Syntaxe.
If you look at the code I did, I had to change a bit your query to do the joins. See if it fits to you.
UPDATE BMR_DWH.dbo.FactVehicleStock as a
INNER JOIN BMR_STAGE.dbo.STG_Traders_Online as B
ON A.StockbookNumber = B.Stock_Number
INNER JOIN
(SELECT Distinct [DEALERSHIP_KEY]
FROM BMR_DWH.[dbo].[DimDealership] as C
INNER JOIN [BMR_STAGE].[dbo].[STG_Traders_Online] E
ON LTRIM(RTRIM(C.MOLNUMBER)) = LTRIM(RTRIM(E.MOL_Number)) ) D
ON A.DEALERSHIP_KEY = D.DEALERSHIP_KEY
SET
FactVehicleStock.[TOL_BidDateTime] = B.Bid_Date_and_Time,
FactVehicleStock.[TOL_AuctionDate] = B.Date_opened_for_tender,
FactVehicleStock.[TOL_OriginalLoadDate] = B.Original_Load_date,
FactVehicleStock.[TOL_ServiceHistory] = B.Service_History,
FactVehicleStock.[TOL_ReservedPrice] = B.Reserve_price,
FactVehicleStock.[TOL_BidPrice] = B.Bid_Price,
FactVehicleStock.[TOL_OriginalReservedPrice] = B.Original_Reserve_Price,
FactVehicleStock.[TOL_NoOfTimesReloaded] = B.Number_of_times_reloaded

SSIS SSQL Task error

I am trying to update a table using a SQL task in SSIS and I'm getting an error: The multi-part identifier "a.SourceSystemKey" could not be bound.
Update BMR_STAGE.dbo.STG_AL_VSAccountStatuses
set a.SourceSystemKey = b.SourceSystemKey
,a.SourceSystem = b.SourceSystem
,a.NLCompany = b.NLCompany
,a.AccountStatus = b.AccountStatus
,a.Description = b.Description
,a.InsertAuditKey = b.InsertAuditKey
,a.UpdateAuditKey = b.UpdateAuditKey
,a.ChangeDate = b.ChangeDate
from BMR_STAGE.dbo.STG_AL_VSAccountStatuses a, BMR_STAGE.dbo.TMP_STG_AL_VSAccountStatuses b
where a.ID =b.ID
That error indicates either that there is no field called a.SourceSystemKey or that the alias a is not recognized in that scope. Try using the explicit join syntax.
Update a
set
a.SourceSystemKey = b.SourceSystemKey
,a.SourceSystem = b.SourceSystem
,a.NLCompany = b.NLCompany
,a.AccountStatus = b.AccountStatus
,a.Description = b.Description
,a.InsertAuditKey = b.InsertAuditKey
,a.UpdateAuditKey = b.UpdateAuditKey
,a.ChangeDate = b.ChangeDate
from BMR_STAGE.dbo.STG_AL_VSAccountStatuses a inner join
BMR_STAGE.dbo.TMP_STG_AL_VSAccountStatuses b on a.ID = b.ID