I am using MS SQL. I want to update a specific row within a table with data from another table. I have created a query that will get the specific row I want to update. Please note that I have used a select query to select the specific row that needs to be updated. Also note that there is a sub query used to get the right row. For me, this makes it difficult to incorporate into a set statement.
select tbl1.assessmentcode, tbl1.Overview from subjectassessmentareas tbl1
inner join
(
select assessmentcode,MIN(areaseq) as minassessarea from subjectassessmentareas
where resultgroup = 'PR_Yr8_2' and ResultType = 'KUS_5'
group by AssessmentCode
) tbl2
on tbl1.AssessmentCode = tbl2.AssessmentCode and tbl1.AreaSeq = tbl2.minassessarea
where fileyear = 2016 and filesemester = 3
This gives me
Now I want to update the overview column with data from another table. This select query gives me the info I want to use to update the other table.
SELECT AssessmentCode, Overview
FROM SubjectAssessments
WHERE (ClassCampus = 'S')
and (FileYear = 2015)
and (FileSemester = 3)
and filetype = 'A'
and AssessmentCode like '08%'
This gives me
Can someone please help me with the syntax to update the overview column from the row obtained in the first query above with the overview column contained in the second query where the Query1.AssessmentCode = Query2.AssessmentCode from both queries.
How can I use a set statement but then use the first query above to say which row to set? Other similar questions just use a simple set and then a field without any where statements.
Just join these two in an updateable CTE:
;with x as (
select tbl1.assessmentcode, tbl1.Overview
from subjectassessmentareas tbl1
inner join
(
select assessmentcode,MIN(areaseq) as minassessarea from subjectassessmentareas
where resultgroup = 'PR_Yr8_2' and ResultType = 'KUS_5'
group by AssessmentCode
) tbl2
on tbl1.AssessmentCode = tbl2.AssessmentCode and tbl1.AreaSeq = tbl2.minassessarea
where fileyear = 2016 and filesemester = 3
),
y as (
SELECT AssessmentCode, Overview
FROM SubjectAssessments
WHERE (ClassCampus = 'S')
and (FileYear = 2015)
and (FileSemester = 3)
and filetype = 'A'
and AssessmentCode like '08%'
),
z as (
select x.Overview as dest, y.Overview as src
from x join y on x.AssessmentCode = y.AssessmentCode
)
update z set dest = src
Try following:
;WITH cteBaseInfo AS
(
SELECT AssessmentCode, Overview
FROM SubjectAssessments
WHERE (ClassCampus = 'S')
and (FileYear = 2015)
and (FileSemester = 3)
and filetype = 'A'
and AssessmentCode like '08%'
)
, cteToBeUpdated AS
(
select tbl1.assessmentcode, tbl1.Overview from subjectassessmentareas tbl1
inner join
(
select assessmentcode,MIN(areaseq) as minassessarea from subjectassessmentareas
where resultgroup = 'PR_Yr8_2' and ResultType = 'KUS_5'
group by AssessmentCode
) tbl2
on tbl1.AssessmentCode = tbl2.AssessmentCode and tbl1.AreaSeq = tbl2.minassessarea
where fileyear = 2016 and filesemester = 3.
)
UPDATE subjectassessmentareas
SET Overview = (SELECT Overview FROM cteBaseInfo WHERE AssessmentCode = subjectassessmentareas.AssessmentCode)
WHERE AssessmentCode IN (SELECT AssessmentCode FROM cteToBeUpdated)
Please note that, here AssessmentCode should be Primary Key.
Related
I have two huge database tables names "AR" and "All", and I am trying to match records in "AR" to "All", note here we don't have a unique identifier, so I am doing a kind of fuzzy matching using First Name, last name, dob and ssn to get the matches. My match query is working.
The All table has a column "MID" which I want to fetch for my every matched record, but when I try my query I get thousands of records. I searched a lot online but could not figure it out.
I am trying to get the first matched record from "All" table along with corresponding MId, for each and every record in my "AR" table. Can anyone help me out here. My Query is below:
Select distinct a.*,
r."MID"
from "public"."AR" a
inner join "public"."All" r
On ( a."cDOB" = r."cDOB"
and right(a."SSN",4) = right(r."SSN",4)
and left(a."Last Name",4) = left(r."LastName",4)
and (a."SSN"!='' or r."SSN"!='')
)
OR
( left(a."First Name",4) = left(r."FirstName",4)
and ( left(a."Last Name",4) = left(r."LastName",4)
OR right(a."Last Name",4) = right(r."LastName",4)
)
and ( right(a."SSN",4) = r."SSN"
OR a."cDOB" = r."cDOB"
)
and ( a."SSN"!=''
OR r."SSN"!=''
)
)
OR
( a."MelID (Original) " = r."Prp"
and a."cDOB" = r."cDOB"
and r."Prp"!=''
);
The query gives me the correct output if I remove r."MID", from the first line, but when I fetch r."MID" the output records are a lot with duplicates and what not.
To fetch the "first" MID from All for every row in AR, you can use DISTINCT ON:
SELECT DISTINCT ON (a.undisclosed_pk_column)
a.*, r."MID"
FROM ...
...
ORDER BY a.undisclosed_pk_column, r.undisclosed_columns_defining_first;
Related:
Select first row in each GROUP BY group?
I think the problem is that you're doing an inner join with 3 OR conditions, so you get duplicates when a record matches on more than one of them. Try the below where you left join to the "MID" table 3 times and only keep results where at least one matched.
Select distinct a.*,
nvl(nvl(r."MID",r2."MID"),r3."MID") as MID
from "public"."AR" a
left join "public"."All" r
On ( a."cDOB" = r."cDOB"
and right(a."SSN",4) = right(r."SSN",4)
and left(a."Last Name",4) = left(r."LastName",4)
and (a."SSN"!='' or r."SSN"!='')
)
left join "public"."All" r2
On ( left(a."First Name",4) = left(r2."FirstName",4)
and ( left(a."Last Name",4) = left(r2."LastName",4)
OR right(a."Last Name",4) = right(r2."LastName",4)
)
and ( right(a."SSN",4) = r2."SSN"
OR a."cDOB" = r2."cDOB"
)
and ( a."SSN"!=''
OR r2."SSN"!=''
)
)
left join "public"."All" r3
( a."MelID (Original) " = r3."Prp"
and a."cDOB" = r3."cDOB"
and r3."Prp"!=''
)
WHERE (r."MID" IS NOT NULL OR r2."MID" IS NOT NULL OR r3."MID" IS NOT NULL)
;
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?
I'm trying to migrate some tables into an existing table, I need to perform the updates only where DET_ATTACHMENT_ID equals DET_ATTACHMENT.ID, here's the query I have so far.
UPDATE DET_ATTACHMENT
SET attachment_type = 'LAB', -- being added by the query, to replace the table difference
payer_criteria_id = (
SELECT PAYER_CRITERIA_ID
FROM DET_LAB_ATTACHMENT
WHERE DET_LAB_ATTACHMENT.DET_ATTACHMENT_ID = DET_ATTACHMENT.ID)
WHERE exists(
SELECT DET_ATTACHMENT_ID
FROM DET_ATTACHMENT
JOIN DET_LAB_ATTACHMENT ON (ID = DET_ATTACHMENT_ID)
WHERE DET_ATTACHMENT_ID = DET_ATTACHMENT.ID
the problem with the existing query is that it's setting every row to have an attachment_type of "LAB", and nulling out the payer_criteria_id where it didn't match. What am I doing wrong?
The problem might be that your exists(...) predicate always evaluates to true, thus making the update run for all rows of det_attachment. Try it this way:
UPDATE DET_ATTACHMENT X
SET X.attachment_type = 'LAB',
X.payer_criteria_id = (
SELECT C.PAYER_CRITERIA_ID
FROM DET_LAB_ATTACHMENT C
WHERE C.DET_ATTACHMENT_ID = X.ID
)
WHERE
exists(
SELECT 1
FROM DET_ATTACHMENT A
JOIN DET_LAB_ATTACHMENT B
ON B.DET_ATTACHMENT_ID = A.ID
where B.det_attachment_id = X.id
)
;
Looking for results of all rows for those eventIds where there exists a row for that eventId with a particular position and sub position, but there does NOT EXIST any row with that position and a null subposition. I did it in MS SQL using the EXCEPT keyword; however, MS Access fails on EXCEPT. Is there a way to do this query in MS Access:
SELECT Distinct eventID FROM table WHERE Position = '123' AND SubPosition = 'ABC'
AND pool = 'something'
AND Status = 'active'
AND area = '1'
EXCEPT
SELECT Distinct eventID FROM table WHERE Position = '123' AND SubPosition IS NULL
AND pool = 'something'
AND Status = 'active'
AND area = '1'
Thanks
Something along the lines of an outer join to find where there's no null match and then filter on there being no null match.
SELECT *
FROM (select * from Table1 where subposition is not null) as hasSubPosition
left join (select * from Table1 where subposition is null) AS noSubPosition
on
hasSubPosition.eventid = noSubPosition.eventid and
hasSubPosition.position = noSubPosition.position and
hasSubPosition.pool = noSubPosition.pool and
hasSubPosition.status = noSubPosition.status and
hasSubPosition.area = noSubPosition.area
where noSubPosition.eventid is null
I need to select some rows that don't have certain values in 2 columns. Currently I am doing this for a single column by doing the following:
SELECT *
FROM MyTable
WHERE (ManufacturerID = #ManufacturerID)
AND ItemID NOT IN(
SELECT ItemID FROM UpdateMyTable WHERE ManufacturerID=#ManufacturerID
)
But now I need to filter out rows that don't contain 2 column values at the same time: ItemID and ChildItemID
How would I accomplish this?
SELECT
*
FROM
MyTable AS data
LEFT JOIN
(SELECT x, y, z FROM UpdateMyTable) AS check
ON data.x = check.x
AND data.y = check.y
AND data.z = check.z
WHERE
x = #x
AND check.x IS NULL
OR
SELECT
*
FROM
MyTable AS data
WHERE
x = #x
AND NOT EXISTS (
SELECT
*
FROM
UpdateMyTable AS check
WHERE
data.x = check.x
AND data.y = check.y
AND data.z = check.z
)
You could use a JOIN instead of a NOT IN.
SELECT *
FROM MyTable t
INNER JOIN UpdateMyTable u ON t.ManufacturerId = u.ManufacturerId
WHERE t.ManufacturerId = #ManufacturerId
AND t.ItemId != u.ItemId
AND t.ItemId != u.ChildItemId