Query for updating a column in same table from same table - sql

I have to update the authorid column which are matching (where documentculture = 'en-US'
to matching (where documentculture = 'el-GR' in the same table. which includes a inner join to another table
I written like below which looks wrong:
UPDATE t1
SET t1.authorid = t2.authorid
FROM wv_blogdata AS t1
INNER JOIN wv_blogdata AS t2
ON t1.documentnodeid = t2.documentnodeid
inner join CMS_Document d
ON d.BlogDataID = d.DocumentForeignKeyValue
WHERE t2.DocumentCulture = 'en-US';
could you please correct me?
More explanation:
select authorid from wv_blogdata
inner join CMS_Document
on wv_blogdata.BlogDataID = CMS_Document.DocumentForeignKeyValue
Where DocumentCulture ='el-GR'
The author id of above query is different from authorid of below query
which i want to make it synch
select authorid from wv_blogdata
inner join CMS_Document
on wv_blogdata.BlogDataID = CMS_Document.DocumentForeignKeyValue
Where DocumentCulture ='en-US'

As Zohar Peled says in the comments, unless you give sample data, expected results as well as your current DML it's hard to produce an accurate answer to your question.
That being said, in general terms if you can produce a select statement using table aliases that shows both the field to be updated and the field with the new value then you can use it as the basis for a successful UPDATE query.
So if the correct results are shown in this query(your original converted into a SELECT):
SELECT t1.authorid AS OldValue, t2.authorid AS NewValue
FROM wv_blogdata AS t1
INNER JOIN wv_blogdata AS t2
ON t1.documentnodeid = t2.documentnodeid
INNER JOIN CMS_Document d
ON d.BlogDataID = d.DocumentForeignKeyValue
WHERE t2.DocumentCulture = 'en-US';
you will get the correct outcome from this query(your original):
UPDATE t1
SET t1.authorid = t2.authorid
FROM wv_blogdata AS t1
INNER JOIN wv_blogdata AS t2
ON t1.documentnodeid = t2.documentnodeid
INNER JOIN CMS_Document d
ON d.BlogDataID = d.DocumentForeignKeyValue
WHERE t2.DocumentCulture = 'en-US';
Remembering of course to test your work for unexpected outcomes and hidden gotchas.
Again without sufficient sample data it's really hard to give you a definitive answer, so include as much detail as possible to help us help you.
Hope this helps you to work it out.

The following query should make the records in sync so authorid of german blogs and authorid of usa blogs will become the same after you run this query.
Note that top(1) is required so only one value is returned by the sub-query else if there are multiple blog records for german culture you will encounter an error.
UPDATE b
SET b.authorid =
(SELECT top(1) wvb.authorid
FROM wv_blogdata wvb
INNER JOIN CMS_Document cms ON wvb.BlogDataID = cms.DocumentForeignKeyValue
WHERE cms.DocumentCulture ='el-GR' AND b.BlogDataID = cms.DocumentForeignKeyValue order by wvb.authorid)
FROM wv_blogdata b
INNER JOIN CMS_Document ON b.BlogDataID = CMS_Document.DocumentForeignKeyValue
WHERE CMS_Document.DocumentCulture ='en-US';

Related

Why is it not matching?

Code:
(SELECT
[QBDATABASE].[dbo].[itemnoninventory].[FullName],
[LotTracker].[dbo].[tblParts].[PartNo],
[QBDATABASE].[dbo].[itemnoninventory].[CustomField2] AS StdCost,
[QBDATABASE].[dbo].[salesorpurchasedetail].[Price],
[QBDATABASE].[dbo].[itemnoninventory].[ListID],
[QBDATABASE].[dbo].[salesorpurchasedetail].[IDKEY]
FROM
[QBDATABASE].[dbo].[itemnoninventory]
Inner JOIN
[QBDATABASE].[dbo].[salesorpurchasedetail] ON [QBDATABASE].[dbo].[itemnoninventory].[ListID] = [QBDATABASE].[dbo].[salesorpurchasedetail].[IDKEY]
INNER JOIN
[LotTracker].[dbo].[tblParts] ON [QBDATABASE].[dbo].[itemnoninventory].[FullName] like [LotTracker].[dbo].[tblParts].[PartNo]
WHERE ([QBDATABASE].[dbo].[salesorpurchasedetail].[AccountRef_FullName] = 'Inventory, Raw Material')
I added unneeded selects to create the screenshot below of sample results.
ListID is varchar(255), null)
IDKEY is varchar(255), null)
Questions:
What would cause query to not see ListID = IDKEY for the NULL results?
EDIT Goal:
Stdcost should match the Price amount if ListID=IDKEY and FullName=PartNo
This isn't an answer but too long for a comment. Here your exact same query. The ONLY changes I made was a little formatting and removed all those horrifically long object names and used aliases instead.
SELECT
ini.FullName,
p.PartNo,
ini.CustomField2 AS StdCost,
spd.Price,
ini.ListID,
spd.IDKEY
FROM QBDATABASE.dbo.itemnoninventory ini
Inner JOIN QBDATABASE.dbo.salesorpurchasedetail spd ON ini.ListID = spd.IDKEY
INNER JOIN LotTracker.dbo.tblParts p ON ini.FullName like p.PartNo
WHERE spd.AccountRef_FullName = 'Inventory, Raw Material'
The answer to your question is that the row in itemnoninventory contain NULL so of course it will be NULL in the query.
After your edit, you need to have the price returned if CustomField2 is null. This can be done with either ISNULL or COALESCE. ISNULL will return the second value if the first value is null.
(SELECT
[QBDATABASE].[dbo].[itemnoninventory].[FullName],
[LotTracker].[dbo].[tblParts].[PartNo],
ISNULL([QBDATABASE].[dbo].[itemnoninventory].[CustomField2],[QBDATABASE].[dbo].[salesorpurchasedetail].[Price]) AS StdCost,
[QBDATABASE].[dbo].[salesorpurchasedetail].[Price],
[QBDATABASE].[dbo].[itemnoninventory].[ListID],
[QBDATABASE].[dbo].[salesorpurchasedetail].[IDKEY]
FROM
[QBDATABASE].[dbo].[itemnoninventory]
Inner JOIN
[QBDATABASE].[dbo].[salesorpurchasedetail] ON [QBDATABASE].[dbo].[itemnoninventory].[ListID] = [QBDATABASE].[dbo].[salesorpurchasedetail].[IDKEY]
INNER JOIN
[LotTracker].[dbo].[tblParts] ON [QBDATABASE].[dbo].[itemnoninventory].[FullName] like [LotTracker].[dbo].[tblParts].[PartNo]
WHERE ([QBDATABASE].[dbo].[salesorpurchasedetail].[AccountRef_FullName] = 'Inventory, Raw Material')
I cannot upvote. I combined both seans replies and have what I wanted. Ty both.
SELECT
ini.FullName,
p.PartNo,
ISNULL(ini.CustomField2,spd.Price) AS StdCost,
spd.Price,
ini.ListID,
spd.IDKEY
FROM QBDATABASE.dbo.itemnoninventory ini
Inner JOIN QBDATABASE.dbo.salesorpurchasedetail spd ON ini.ListID = spd.IDKEY
INNER JOIN LotTracker.dbo.tblParts p ON ini.FullName like p.PartNo
WHERE spd.AccountRef_FullName = 'Inventory, Raw Material'

View data from one table but based on other table (SQL Server)

I want to display all information of table program but it must based on other table (which is Line), I try to use join but it will show ALL information from ALL TABLE.
Can someone help me to create the query or just tell me what should i do.
TABLE LINE
------------
LineName
TABLE PACKAGE
-------------
PackageNo
PackageName
Line
TABLE FAMILY
------------
FamilyCode
FamilyName
TestQuant
TABLE PROGRAM
-------------
FamilyName
TestType
FolderPath
TestProgram
Remark
CreateTime
And this is what i have done
SELECT * FROM Program AS D
JOIN Family AS Q ON D.FamilyName = Q.FamilyName
JOIN Process AS V ON Q.TestQuant = V.PackageNo
JOIN Line AS R ON R.LineName = V.Line
WHERE V.Line = 'LINE1'
WHAT I HAVE CHANGE
SELECT DISTINCT D.FamilyName, D.TestType, D.FolderPath, D.TestProgram, D.Remark,
D.CreateTime
FROM Program D
INNER JOIN Family Q ON D.FamilyName = Q.FamilyName
INNER JOIN Process V ON Q.TestQuant = V.PackageNo
INNER JOIN Line R ON R.LineName = V.Line
WHERE V.Line = 'LINE1'
If you need ONLY the data from Program table, try this:
SELECT D.FamilyName, D.TestType, D.FolderPath, D.TestProgram, D.Remark, D.CreateTime
FROM Program D
JOIN Family Q ON D.FamilyName = Q.FamilyName
JOIN Process V ON Q.TestQuant = V.PackageNo
JOIN Line R ON R.LineName = V.Line
WHERE V.Line = 'LINE1'
It sounds like you may need a left or right outer join. Here is an example question that has some very good explanations of JOINs in the answers, the venn diagrams really helped me understand:
SQL JOIN and different types of JOINs
An example of how you might construct a join (taken from Techonthenet)
SELECT columns
FROM table1
RIGHT [OUTER] JOIN table2
ON table1.column = table2.column;
Hope this helps, SQL JOIN can be a bit tricky to understand.

Postgresql - Having trouble performing left joins on multiple tables

I'm in the process of moving some Mysql queries over to Postgresql and I ran across this one that doesn't work.
select (tons of stuff)
from trip_publication
left join trip_collection AS "tc" on
tc.id = tp.collection_id
left join
trip_author ta1, (dies here)
trip_person tp1,
trip_institution tai1,
trip_location tail1,
trip_rank tr1
ON
tp.id = ta1.publication_id
AND tp1.id = ta1.person_id
AND ta1.order = 1
AND tai1.id = ta1.institution_id
AND tail1.id = tai1.location_id
AND ta1.rank_id = tr1.id
The query seems to be dying on the "trip_author ta1" line, where I marked it above. The actual error message is:
syntax error at or near ","
LINE 77: (trip_author ta1, trip_person tp1, ...
I went through the docs, and it seems to be correct. What exactly am I doing wrong here? Any feedback would be much appreciated.
I don't know postgres, but in regular SQL you would need to a series of LEFT JOIN statements rather than your comma syntax. You seemed to have started this then stopped after the first two.
Something like:
SELECT * FROM
table1
LEFT JOIN table2 ON match1
LEFT JOIN table3 ON match2
WHERE otherFilters
The alternative is the older SQL syntax of:
SELECT cols
FROM table1, table2, table3
WHERE match AND match2 AND otherFilters
There's a couple of other smaller errors in your SQL, like the fact you forgot your tp alias on your first table, and have tried including a where clause (ta1.order = 1) as a joining constraint.
I think this is what you are after:
select (tons of stuff)
from trip_publication tp
left join trip_collection AS "tc" on tc.id = tp.collection_id
left join trip_author ta1 on ta1.publication_id = tp.id
left join trip_person tp1 on tp1.id = ta1.person_id
left join trip_institution tai1 on tai1.id = ta1.institution_id
left join trip_location tail1 on tail1.id = tai1.location_id
left join trip_rank tr1 on tr1.id = ta1.rank_id
where ta1.order = 1
Your left joins are one per table you are joining
left join trip_author ta1 on ....
left join trip_person tp1 on ....
left join trip_institution on ...
...and so on

Super Slow Query - sped up, but not perfect... Please help

I posted a query yesterday (see here) that was horrible (took over a minute to run, resulting in 18,215 records):
SELECT DISTINCT
dbo.contacts_link_emails.Email, dbo.contacts.ContactID, dbo.contacts.First AS ContactFirstName, dbo.contacts.Last AS ContactLastName, dbo.contacts.InstitutionID,
dbo.institutionswithzipcodesadditional.CountyID, dbo.institutionswithzipcodesadditional.StateID, dbo.institutionswithzipcodesadditional.DistrictID
FROM
dbo.contacts_def_jobfunctions AS contacts_def_jobfunctions_3
INNER JOIN
dbo.contacts
INNER JOIN
dbo.contacts_link_emails
ON dbo.contacts.ContactID = dbo.contacts_link_emails.ContactID
ON contacts_def_jobfunctions_3.JobID = dbo.contacts.JobTitle
INNER JOIN
dbo.institutionswithzipcodesadditional
ON dbo.contacts.InstitutionID = dbo.institutionswithzipcodesadditional.InstitutionID
LEFT OUTER JOIN
dbo.contacts_def_jobfunctions
INNER JOIN
dbo.contacts_link_jobfunctions
ON dbo.contacts_def_jobfunctions.JobID = dbo.contacts_link_jobfunctions.JobID
ON dbo.contacts.ContactID = dbo.contacts_link_jobfunctions.ContactID
WHERE
(dbo.contacts.JobTitle IN
(SELECT JobID
FROM dbo.contacts_def_jobfunctions AS contacts_def_jobfunctions_1
WHERE (ParentJobID <> '1841')))
AND
(dbo.contacts_link_emails.Email NOT IN
(SELECT EmailAddress
FROM dbo.newsletterremovelist))
OR
(dbo.contacts_link_jobfunctions.JobID IN
(SELECT JobID
FROM dbo.contacts_def_jobfunctions AS contacts_def_jobfunctions_2
WHERE (ParentJobID <> '1841')))
AND
(dbo.contacts_link_emails.Email NOT IN
(SELECT EmailAddress
FROM dbo.newsletterremovelist AS newsletterremovelist))
ORDER BY EMAIL
With a lot of coaching and research, I've tuned it up to the following:
SELECT contacts.ContactID,
contacts.InstitutionID,
contacts.First,
contacts.Last,
institutionswithzipcodesadditional.CountyID,
institutionswithzipcodesadditional.StateID,
institutionswithzipcodesadditional.DistrictID
FROM contacts
INNER JOIN contacts_link_emails ON
contacts.ContactID = contacts_link_emails.ContactID
INNER JOIN institutionswithzipcodesadditional ON
contacts.InstitutionID = institutionswithzipcodesadditional.InstitutionID
WHERE
(contacts.ContactID IN
(SELECT contacts_2.ContactID
FROM contacts AS contacts_2
INNER JOIN contacts_link_emails AS contacts_link_emails_2 ON
contacts_2.ContactID = contacts_link_emails_2.ContactID
LEFT OUTER JOIN contacts_def_jobfunctions ON
contacts_2.JobTitle = contacts_def_jobfunctions.JobID
RIGHT OUTER JOIN newsletterremovelist ON
contacts_link_emails_2.Email = newsletterremovelist.EmailAddress
WHERE (contacts_def_jobfunctions.ParentJobID <> 1841)
GROUP BY contacts_2.ContactID
UNION
SELECT contacts_1.ContactID
FROM contacts_link_jobfunctions
INNER JOIN contacts_def_jobfunctions AS contacts_def_jobfunctions_1 ON
contacts_link_jobfunctions.JobID = contacts_def_jobfunctions_1.JobID
AND contacts_def_jobfunctions_1.ParentJobID <> 1841
INNER JOIN contacts AS contacts_1 ON
contacts_link_jobfunctions.ContactID = contacts_1.ContactID
INNER JOIN contacts_link_emails AS contacts_link_emails_1 ON
contacts_link_emails_1.ContactID = contacts_1.ContactID
LEFT OUTER JOIN newsletterremovelist AS newsletterremovelist_1 ON
contacts_link_emails_1.Email = newsletterremovelist_1.EmailAddress
GROUP BY contacts_1.ContactID))
While this query is now super fast (about 3 seconds), I've blown part of the logic somewhere - it only returns 14,863 rows (instead of the 18,215 rows that I believe is accurate).
The results seem near correct. I'm working to discover what data might be missing in the result set.
Can you please coach me through whatever I've done wrong here?
Thanks,
Russell Schutte
The main problem with your original query was that you had two extra joins just to introduce duplicates and then a DISTINCT to get rid of them.
Use this:
SELECT cle.Email,
c.ContactID,
c.First AS ContactFirstName,
c.Last AS ContactLastName,
c.InstitutionID,
izip.CountyID,
izip.StateID,
izip.DistrictID
FROM dbo.contacts c
INNER JOIN
dbo.institutionswithzipcodesadditional izip
ON izip.InstitutionID = c.InstitutionID
INNER JOIN
dbo.contacts_link_emails cle
ON cle.ContactID = c.ContactID
WHERE cle.Email NOT IN
(
SELECT EmailAddress
FROM dbo.newsletterremovelist
)
AND EXISTS
(
SELECT NULL
FROM dbo.contacts_def_jobfunctions cdj
WHERE cdj.JobId = c.JobTitle
AND cdj.ParentJobId <> '1841'
UNION ALL
SELECT NULL
FROM dbo.contacts_link_jobfunctions clj
JOIN dbo.contacts_def_jobfunctions cdj
ON cdj.JobID = clj.JobID
WHERE clj.ContactID = c.ContactID
AND cdj.ParentJobId <> '1841'
)
ORDER BY
email
Create the following indexes:
newsletterremovelist (EmailAddress)
contacts_link_jobfunctions (ContactID, JobID)
contacts_def_jobfunctions (JobID)
Do you get the same results when you do:
SELECT count(*)
FROM
dbo.contacts_def_jobfunctions AS contacts_def_jobfunctions_3
INNER JOIN
dbo.contacts
INNER JOIN
dbo.contacts_link_emails
ON dbo.contacts.ContactID = dbo.contacts_link_emails.ContactID
ON contacts_def_jobfunctions_3.JobID = dbo.contacts.JobTitle
SELECT COUNT(*)
FROM
contacts
INNER JOIN contacts_link_jobfunctions
ON contacts.ContactID = contacts_link_jobfunctions.ContactID
INNER JOIN contacts_link_emails
ON contacts.ContactID = contacts_link_emails.ContactID
If so keep adding each join conditon on until you don't get the same results and you will see where your mistake was. If all the joins are the same, then look at the where clauses. But I will be surprised if it isn't in the first join because the syntax you have orginally won't even work on SQL Server and it is pretty nonstandard SQL and may have been incorrect all along but no one knew.
Alternatively, pick a few of the records that are returned in the orginal but not the revised. Track them through the tables one at a time to see if you can find why the second query filters them out.
I'm not directly sure what is wrong, but when I run in to this situation, the first thing I do is start removing variables.
So, comment out the where clause. How many rows are returned?
If you get back the 11,604 rows then you've isolated the problems to the joins. Work though the joins, commenting each one out (remove the associated columns too) and figure out how many rows are eliminated.
As you do this, aim to find what is causing the desired rows to be eliminated. Once isolated, consider the join differences between the first query and the second query.
In looking at the first query, you could probably just modify that to eliminate any INs and instead do a EXISTS instead.
Consider your indexes as well. Any thing in the where or join clauses should probably be indexed.

Selecting the first row out of many sql joins

Alright, so I'm putting together a path to select a revision of a particular novel:
SELECT Catalog.WbsId, Catalog.Revision, NovelRevision.Revision
FROM Catalog, BookInCatalog
INNER JOIN NovelMaster
INNER JOIN HasNovelRevision
INNER JOIN NovelRevision
ON HasNovelRevision.right = NovelRevision.obid
ON HasNovelRevision.Left=NovelMaster.obid
ON NovelMaster.obid = BookInCatalog.Right
WHERE Catalog.obid = BookInCatalog.Left;
This returns all revisions that are in the Novel Master for each Novel Master that is in the catalog.
The problem is, I only want the FIRST revision of each novel master in the catalog. How do I go about doing that? Oh, and btw: my flavor of sql is hobbled, as many others are, in that it does not support the LIMIT Function.
****UPDATE****
So using answer 1 as a guide I upgraded my query to this:
SELECT Catalog.wbsid
FROM Catalog, BookInCatalog, NovelVersion old, NovelMaster, HasNovelRevision
LEFT JOIN NovelVersion newRevs
ON old.revision < newRevs.revision AND HasNovelRevision.right = newRevs.obid
LEFT JOIN HasNovelRevision NewerHasNovelRevision
ON NewerHasNovelRevision.right = newRevs.obid
LEFT JOIN NovelMaster NewTecMst
ON NewerHasNovelRevision.left = NewTecMst.obid
WHERE Catalog.programName = 'E18' AND Catalog.obid = BookInCatalog.Left
AND BookInCatalog.right = NewTecMst.obid AND newRevs.obid = null
ORDER BY newRevs.documentname;
I get an error on the fourth line:
"old"."revision": invalid identifier
SOLUTION
Well, I had to go to another forum, but I got a working solution:
select nr1.title, nr1.revision
from novelrevision nr1
where nr1.revision in (select min(revision) from novelrevision nr2
where nr1.title = nr2.title)
So this solution uses the JOIN mentioned by the OA, along with the IN keyword to match it to a revision.
Something like this might work, it's called an exclusive left join:
....
INNER JOIN NovelRevision
ON HasNovelRevision.right = NovelRevision.obid
LEFT JOIN NovelRevision as NewerRevision
ON HasNovelRevision.right = NewerRevision.obid
AND NewerRevision.revision > NovelRevision.revision
...
WHERE NeverRevision.obid is null
The where clause filters out rows for which a newer revision exists. This effectively limits the query to the newest revisions.
In response to your comment, you could filter out only revisions that have a newer revision in the same NovelMaster. For example:
....
LEFT JOIN NovelRevision as NewerRevision
ON HasNovelRevision.right = NewerRevision.obid
AND NewerRevision.revision > NovelRevision.revision
LEFT JOIN HasNovelRevision as NewerHasNovelRevision
ON NewerHasNovelRevision.right = NewerRevision.obid
LEFT JOIN NovelMaster as NewerNovelMaster
ON NewerHasNovelRevision.left = NewerNovelMaster.obid
AND NewerNovelMaster.obid = NovelMaster.obid
....
WHERE NeverNovelMaster.obid is null
P.S. I don't think you can group JOINs and follow them with a group of ON conditions. An ON must directly follow its JOIN.
You can use CTE
Check this
WITH NovelRevesion_CTE(obid,RevisionDate)
AS
(
SELECT obid,MIN(RevisionDate) RevisionDate FROM NovelRevision Group by obid
)
SELECT Catalog.WbsId, Catalog.Revision, NovelRevision.Revision
FROM Catalog, BookInCatalog
INNER JOIN NovelMaster
INNER JOIN HasNovelRevision
INNER JOIN NovelRevesion
INNER JOIN NovelRevesion_CTE
ON HasNovelRevision.[right] = NovelRevision.obid
ON HasNovelRevision.[Left]=NovelMaster.obid
ON NovelMaster.obid = BookInCatalog.[Right]
ON NovelRevesion_CTE.obid = NovelRevesion.obid
WHERE Catalog.obid = BookInCatalog.[Left];
First it select the first revision written for each novel (assuming obid is novel foriegn key) by taking the smallest date and group them.
then add it as join in your query