The script below returns the 01427 error that the single row sub-query returns more than one row. The rownum<2 gets a few rows updated. The obvious solution is looping through with pl/sql, but I am trying to determine if there is a SQL only solution.
UPDATE ldl.clens le
SET master_song_id =
(SELECT cf.song_id#
FROM lt.master_songs cf
WHERE le.lot_id = cf.lot_id
AND song_id#_fk =
(SELECT msc_songs.song_id#
FROM lt.msc_songs
WHERE msc_songs.song_name = le.song_name)
---- AND ROWNUM < 2
);
Any and all help and suggestions deeply appreciated!
MD
I'm not sure I grasped the relation between the tables, but if I did, you can use below UPDATE:
UPDATE ldl.clens le
SET master_song_id =
(SELECT cf.song_id#
FROM lt.master_songs cf
JOIN lt.msc_songs ms ON (cf.song_id#_fk = ms.song_id#)
WHERE
ms.song_name = le.song_name
AND le.lot_id = cf.lot_id)
;
It will work if msc_songs.song_name and master_songs.lot_id will give you a unique master_songs.song_id#.
Related
I am having a hard time using MS Access because the syntax is a little finicky compared to other db's.
I am trying to validate a table and compare that table to a master table with multiple columns of information. At the moment I am trying to update a table with a field name of Difference_Value in table ct2011 to be equal to (ct2011.Distribution_Amount - AggregateFinal.SumOfDollars).
Also specifying the lines in which are going to be updated because not all rows in the MASTER are in the table ct2011.
Below is my query.
UPDATE ct2011
SET ct2011.Difference_Value = (ct2011.Distribution_Amount - AggregateFinal.SumOfDollars)
FROM
ct2011 as ct
INNER JOIN
AggregateFinal af
ON
ct.Employee_ID = af.EmpId AND ct.Legal_Name = af.LegalName AND ct.Distribution_Plan_Year = af.CalculationAwardPeriod AND ct.Award_Year = af.AwardPeriod;
I am getting a Syntax error (missing operator). It specifies that it is encountering the error during the SET expressions after the =.
In an MS Access update query, the join criteria should follow the update keyword, e.g.:
update
ct2011 ct inner join aggregatefinal af on
ct.employee_id = af.empid and
ct.legal_name = af.legalname and
ct.distribution_plan_year = af.calculationawardperiod and
ct.award_year = af.awardperiod
set
ct.difference_value = (ct.distribution_amount - af.sumofdollars)
Below sql query is taking too much time for execution. It might be due to repetitive use of same table in from clause. I am not able to find out how to fix this query so that performance would be improve.
Can anyone help me out with this?
Thanks in advance !!
select --
from t_carrier_location act_end,
t_location end_loc,
t_carrier_location act_start,
t_location start_loc,
t_vm_voyage_activity va,
t_vm_voyage v,
t_location_position lp_start,
t_location_position lp_end
where act_start.carrier_location_id = va.carrier_location_id
and act_start.carrier_id = v.carrier_id
and act_end.carrier_location_id =
decode((select cl.carrier_location_id
from t_carrier_location cl
where cl.carrier_id = act_start.carrier_id
and cl.carrier_location_no =
act_start.carrier_location_no + 1),
null,
(select cl2.carrier_location_id
from t_carrier_location cl2, t_vm_voyage v2
where v2.hire_period_id = v.hire_period_id
and v2.voyage_id =
(select min(v3.voyage_id)
from t_vm_voyage v3
where v3.voyage_id > v.voyage_id
and v3.hire_period_id = v.hire_period_id)
and v2.carrier_id = cl2.carrier_id
and cl2.carrier_location_no = 1),
(select cl.carrier_location_id
from t_carrier_location cl
where cl.carrier_id = act_start.carrier_id
and cl.carrier_location_no =
act_start.carrier_location_no + 1))
and lp_start.location_id = act_start.location_id
and lp_start.from_date <=
nvl(act_start.actual_dep_time, act_start.actual_arr_time)
and (lp_start.to_date is null or
lp_start.to_date >
nvl(act_start.actual_dep_time, act_start.actual_arr_time))
and lp_end.location_position_id = act_end.location_id
and lp_end.from_date <=
nvl(act_end.actual_dep_time, act_end.actual_arr_time)
and (lp_end.to_date is null or
lp_end.to_date >
nvl(act_end.actual_dep_time, act_end.actual_arr_time))
and act_end.location_id = end_loc.location_id
and act_start.location_id = start_loc.location_id;
There is no Stright forward one answer for your question and the query you've mentioned.
In order to get a better response time of any query, you need to keep few things in mind while writing your queries. I will mention few here which appeared to be important for your query
Use joins instead of subqueries.
Use EXPLAIN to determine queries are functioning appropriately.
Use the columns which are having indexes with your where clause else create an index on those columns. here use your common sense which are the columns to be indexed ex: foreign key columns, deleted, orderCreatedAt, startDate etc.
Keep the order of the select columns as they appear at the table instead of arbitrarily selecting columns.
The above four points are enough for the query you've provided.
To dig deep about SQL optimization and tuning refer this https://docs.oracle.com/database/121/TGSQL/tgsql_intro.htm#TGSQL130
This SQL is beyond my expertise. I think it should be fairly easy for someone with experience. Here is what I have so far..
SQL is as follows:
UPDATE (Tbl_Stg_Project_Schedule_Dates
INNER JOIN Tbl_Child_ITN ON Tbl_Stg_Project_Schedule_Dates.ms_itn = Tbl_Child_ITN.ITN)
INNER JOIN Tbl_Schedule ON Tbl_Child_ITN.Id = Tbl_Schedule.ID SET Tbl_Schedule.a_construction_start = [Tbl_Stg_Project_Schedule_Dates].[ms_start_date]
WHERE (((Tbl_Stg_Project_Schedule_Dates.ms_tempt_id) In (16,17,18,19,20,21,22,23)));
I want to add one last condition to this being that I only want the minimum of [Tbl_Stg_Project_Schedule_Dates].[ms_start_date] to update the table. I've tried the obvious of wrapping the field in Min, and also tried creating a separate aggregate select statement first (to get the min value with other criteria) that I then tried to create the update query from in new query but no luck.
I believe this is valid Access/Jet SQL. The idea here is to use a subquery to look up the earliest date among all the rows in your subset. I'm not sure if ms_itn was the right column to correlate on but hopefully you get the idea:
UPDATE (Tbl_Stg_Project_Schedule_Dates
INNER JOIN Tbl_Child_ITN ON Tbl_Stg_Project_Schedule_Dates.ms_itn = Tbl_Child_ITN.ITN)
INNER JOIN Tbl_Schedule ON Tbl_Child_ITN.Id = Tbl_Schedule.ID
SET Tbl_Schedule.a_construction_start = [Tbl_Stg_Project_Schedule_Dates].[ms_start_date]
WHERE (((Tbl_Stg_Project_Schedule_Dates.ms_tempt_id) In (16,17,18,19,20,21,22,23)))
and [Tbl_Stg_Project_Schedule_Dates].[ms_start_date] = (
select min(sd.[ms_start_date])
from [Tbl_Stg_Project_Schedule_Dates] as sd
where sd.ms_itn = [Tbl_Stg_Project_Schedule_Dates].ms_itn
)
trying to update a single column based on criteria. The rows that need to be updated are returned by the query
SELECT
it.objectid,
it.versionnumber,
it.itemnumber "Item Number",
it.itemtype,
itcovprem.basisofsettlement,
itcovprem.coverage "Coverage"
FROM
itemcoveragesandpremiums itcovprem,
items it,
policies pl
WHERE
pl.objectid = it.parentobjectid AND
pl.policytype in ('H','F') AND
it.objectid = itcovprem.itemobjectid AND
it.itemtype in ('SHOA','SHOB','SHOC','SHOD','SHOK','SHOL') and
it.versionnumber = itcovprem.itemversionnumber AND
((itcovprem.coverage like ('A - Dwg Bldg%')) or
(itcovprem.coverage like ('#42 - Repl Cost Plus%')) or
(itcovprem.coverage like ('#42 - Limited GRC%'))) and
it.effectivedate >= TO_DATE('01-JAN-2006', 'DD-MON-YYYY') and
exists (select * from itemcoveragesandpremiums icp where icp.itemobjectid = it.objectid and icp.itemversionnumber = it.versionnumber and icp.coverage like ('#42%')) and
itcovprem.basisofsettlement not in ('LGRC')
I've tried a few options to convert this to an update query, but no joy.
I get Error - line 3 - SQL command not properly ended when using
update itemcoveragesandpremiums
set basisofsettlement = 'LGRC'
from itemcoveragesandpremiums as itcovprem
inner join items as it
on it.objectid = itcovprem.itemobjectid and it.versionnumber = itcovprem.itemversionnumber
inner join policies as pl
on pl.objectid = it.parentobjectid
where [cut, rest of query was below]
I get Error - line 6 - missing right parenthesis when trying use an inline query
update
(
SELECT
itcovprem.basisofsettlement as OLD
FROM
itemcoveragesandpremiums as itcovprem inner join items as it on it.objectid = itcovprem.itemobjectid and it.versionnumber = itcovprem.itemversionnumber inner join policies AS pl on pl.objectid = it.parentobjectid
WHERE [query snipped]
) t
set t.old = 'LGRC'
Seems that SQL*Plus just wants to stop looking at the update before it gets to the meat of my select query. I'm not sure if I'm formatting it incorrectly or going at it from the wrong direction. Any advice?
In your first attempt, the error at line 3 is because update doesn't support a from or join clause. In your second attempt the immediate error at line 6 is because you're trying to alias a table with as itcovprem; but you can only use as for column aliases, not for table aliases. (The first attempt is trying to do that too, but it isn't getting as far as encountering that problem). But you can't generally update an inline-view with joins anyway, so it would still error with that - something like an ORA-01779.
You would need to do something like:
update itemcoveragesandpremiums
set basisofsettlement = 'LGRC'
where (itemobjectid, itemversionnumber, basisofsettlement, coverage) in (
select it.objectid,
it.versionnumber,
itcovprem.basisofsettlement,
itcovprem.coverage
from ...
)
Assuming that itemobjectid, itemversionnumber, basisofsettlement, coverage identifies a row sufficiently such that you don't risk updating anything you shouldn't. It might be safer to add a rowid to the select and use that for the update instead to avoid ambiguity:
update itemcoveragesandpremiums
set basisofsettlement = 'LGRC'
where rowid in (
select itcovprem.rowid as target_rowid
from ...
)
I'm working with PeopleSoft Campus Solutions, and we need to update about 22,000 rows of data. This is data between the tables of ACAD_PLAN_VW and ACAD_PROG. Students are listed on both, so their IDs match between the two.
Basically what we are trying to do is say that when the ID, academic career, student career number, effective sequence, and effective date match, AND where the academic plan (their degree, as stored on the ACAD_PLAN_VW) is a specific value, update the ACAD_PROG on the ACAD_PROG table to X value.
I tried to do some very interesting combinations of FROM statements, constantly getting errors. After some researching, I found out that SQLTools doesn't really like FROM statements within UPDATE statements, so I rewrote it to just make the connections manually. I'm assuming I'm doing this right, unless I need to reword it.
The statement I have is:
UPDATE PS_ACAD_PROG SET PS_ACAD_PROG.ACAD_PROG = 'UGDS'
WHERE PS_ACAD_PLAN_VW.EMPLID = PS_ACAD_PROG.EMPLID
AND PS_ACAD_PLAN_VW.ACAD_CAREER = PS_ACAD_PROG.ACAD_CAREER
AND PS_ACAD_PLAN_VW.STDNT_CAR_NBR = PS_ACAD_PROG.STDNT_CAR_NBR
AND PS_ACAD_PLAN_VW.EFFSEQ = PS_ACAD_PROG.EFFSEQ
AND PS_ACAD_PLAN_VW.EFFDT = PS_ACAD_PROG.EFFDT
AND PS_ACAD_PLAN_VW.ACAD_PLAN = 'DSTDS'
Theoretically, I would assume that this would update any student who has those connections. However, the error that I'm currently getting is as follows:
ORA-00904: "PS_ACAD_PLAN_VW"."ACAD_PLAN": invalid identifier
I have, as of yet, been unable to figure out the issue. I do have the correct access to view and update those fields, and the field does indeed exist.
Oracle doesn't know it should use the PS_ACAD_PLAN_VW table. Somehow you should reference it.
For example can you try this way?
UPDATE (
select
PS_ACAD_PROG.ACAD_PROG,
PS_ACAD_PLAN_VW.ACAD_PLAN
from
PS_ACAD_PROG,
PS_ACAD_PLAN_VW
where
PS_ACAD_PLAN_VW.EMPLID = PS_ACAD_PROG.EMPLID
AND PS_ACAD_PLAN_VW.ACAD_CAREER = PS_ACAD_PROG.ACAD_CAREER
AND PS_ACAD_PLAN_VW.STDNT_CAR_NBR = PS_ACAD_PROG.STDNT_CAR_NBR
AND PS_ACAD_PLAN_VW.EFFSEQ = PS_ACAD_PROG.EFFSEQ
AND PS_ACAD_PLAN_VW.EFFDT = PS_ACAD_PROG.EFFDT
)
SET
ACAD_PROG = 'UGDS'
WHERE
ACAD_PLAN = 'DSTDS'
Try to use the table which is not getting identified,by keeping in where clause so that you can use the select statement.That will help identifying the tables.
The following implementation should work:
UPDATE PS_ACAD_PROG
SET ACAD_PROG = 'UGDS'
WHERE ROWID IN(SELECT PROG.ROWID
FROM PS_ACAD_PROG PROG
, PS_ACAD_PLAN_VW PLAN
WHERE PLAN.EMPLID = PROG.EMPLID
AND PLAN.ACAD_CAREER = PROG.ACAD_CAREER
AND PLAN.STDNT_CAR_NBR = PROG.STDNT_CAR_NBR
AND PLAN.EFFSEQ = PROG.EFFSEQ
AND PLAN.EFFDT = PROG.EFFDT
AND PLAN.ACAD_PLAN = 'DSTDS');