Update with Inner join or subquery - multiple relations - sql-server

I need and update on Table exp_pedcom on cases where a field of another table are null ( EXP_Procimp), but these two table do not have a direct relation to each other, so I actully need to "route" it though two other tables in order to relate them. The "routed! relation works, it returns as expected, but the update doesn't. I've tryed both as a direct inner join using from and as a subquery ( which is actually easier to demonstrate, so That's what goes here.
UPDATE EXP_PEDCOM
SET STATUS_ATENDIMENTO=0
WHERE EXP_PROCIMP.DAT_RECEBIMENTO IS NOT NULL IN (SELECT EXP_PROCIMP.DAT_RECEBIMENTO
FROM
EXP_PEDCOM INNER JOIN
EXP_INVOICE_IT ON EXP_PEDCOM.NUM_PEDCOM = EXP_INVOICE_IT.NUM_PEDCOM INNER JOIN
EXP_INVOICE ON EXP_INVOICE_IT.COD_DOCUMENTO = EXP_INVOICE.COD_DOCUMENTO INNER JOIN
EXP_PROCIMP ON EXP_INVOICE.NUM_PROCIMP = EXP_PROCIMP.NUM_PROCIMP)
Any tips?

The following shows how to use it using the UPDATE... FROM... syntax. (I messed with formatting and aliases while working out what the query actually did.)
UPDATE EXP_PEDCOM
set STATUS_ATENDIMENTO = 0
from EXP_PEDCOM
inner join EXP_INVOICE_IT it
on EXP_PEDCOM.NUM_PEDCOM = it.NUM_PEDCOM
inner join EXP_INVOICE iv
on it.COD_DOCUMENTO = iv.COD_DOCUMENTO
inner join EXP_PROCIMP pr
on iv.NUM_PROCIMP = pr.NUM_PROCIMP
where pr.DAT_RECEBIMENTO is not null
This will work [caveat: I could not run and so debug possible syntax glitches], but it's hard to explain why/how this works. It's also a tad unconventional; hopefully you'll get other posts that show the "proper" way to run such queries.

Related

INNER JOIN not working for the first table in a multi table select statement

I am trying to select data from same table twice and it works but it is not allowing me to use the first table in the list in INNER JOIN, if I use the second table from the list in the join it works
So this is the query that works fine
SELECT
TOP 1
RIT_First.LastModified,
RIT_Last.LastModified
FROM
dbo.ItemTransaction RIT_First,
dbo.ItemTransaction RIT_Last
JOIN dbo.Item RI ON RIT_Last.ItemId = RI.Id -- Using the second table in the join
But when I do this
SELECT
TOP 1
RIT_First.LastModified,
RIT_Last.LastModified
FROM
dbo.ItemTransaction RIT_First,
dbo.ItemTransaction RIT_Last
JOIN dbo.Item RI ON RIT_First.ItemId = RI.Id -- Using the first table in the join
I start getting this error
The multi-part identifier "RIT_First.ItemId" could not be bound.
So is it like we can use only last table in the list of tables in the join or I am doing something wrong?
The problem here is your mix and matching of ANSI-89 JOINs and ANSI-92 JOINs. Just don't use ANSI-89 JOINs any more; they were superseded 30 years ago.
If you use ANSI-92 JOINs the whole way through, you don't have a problem:
SELECT TOP (1)
RIT_First.LastModified,
RIT_Last.LastModified
FROM dbo.ItemTransaction RIT_First
CROSS JOIN dbo.ItemTransaction RIT_Last
JOIN dbo.Item RI ON RIT_First.ItemId = RI.Id
ORDER BY {Expression(s)};
If, for some bizarre reason, you are compelled to use an ANSI-89 JOIN, then you would need to put the join criteria in the WHERE:
SELECT TOP (1)
RIT_First.LastModified,
RIT_Last.LastModified
FROM dbo.ItemTransaction RIT_First,
dbo.ItemTransaction RIT_Last,
dbo.Item RI
WHERE RIT_First.ItemId = RI.Id
ORDER BY {Expression(s)};
But, like I said, just don't do that. See this article by Aaron Bertrand for more information: Bad Habits to Kick : Using old-style JOINs

How can I get 3 tables INNER JOIN in MS SQL Server

From the specialist table, retrieve the first name, last name and contact number for the people that provide care to penguins from the species table.
There are 3 tables: tbl_specialist, tbl_species, tbl_care
I need help trying to INNER JOIN the tables to display First, Last, And Contact for penguins.
SELECT specialist_fname, specialist_lname, specialist_contact
FROM ((tbl_specialist
INNER JOIN tbl_species ON species_care = tbl_species.species_care)
INNER JOIN tbl_care ON care_id = tbl_care.care_id)
WHERE species_name = 'penguin'
;
It's a bit difficult without seeing the exact schema of the tables, but your syntax for the subquery is a bit off and you need to alias columns that are found in multiple tables in a JOIN statment. Try rewriting your SQL like this:
SELECT spl.specialist_fname, spl.specialist_lname, spl.specialist_contact
FROM tbl_specialist spl
INNER JOIN tbl_species s
ON spl.species_care = s.species_care
INNER JOIN tbl_care c
ON s.care_id = c.care_id
WHERE s.species_name = 'penguin'
I'm obviously inferring which tables certain columns come from in the join, but hopefully you get the idea.
I figured it out thank you.
SELECT specialist_fname, specialist_lname, specialist_contact
FROM ((tbl_specialist
INNER JOIN tbl_care ON tbl_care.care_specialist = tbl_specialist.specialist_id)
INNER JOIN tbl_species ON tbl_species.species_care= tbl_care.care_id)
WHERE species_name = 'penguin'
;

Using multiple update or inner join is better for performance

I have the following update statement I use in trigger that have same behavior and both of it is correct but 2nd one have problem if I update both tableA_ID and ValueB at same times. But this not big issue as there is work around but if possible I want to avoid it. So what I want to know is there a big performance between this 2 and it will make me decide which one to go. If 2nd much better in performance than I will use 2nd one. But if the difference not that big I will use 1st one. I not expert in sql server. Anyone can help?
UPDATE tableA
SET tableA.Value = tableA.Value - old.ValueB
FROM tableA
INNER JOIN (
SELECT tableA_ID ,ValueB
FROM deleted
) old ON old.tableA_ID = tableA.ID
UPDATE tableA
SET tableA.Value = tableA.Value + new.ValueB
FROM tableA
INNER JOIN (
SELECT tableA_ID ,ValueB
FROM inserted
) new ON new.tableA_ID = tableA.ID
UPDATE tableA
SET tableA.Value = tableA.Value - old.ValueB + new.ValueB
FROM tableA
INNER JOIN (
SELECT tableA_ID ,ValueB
FROM deleted
) old ON old.tableA_ID = tableA.ID
INNER JOIN (
SELECT tableA_ID ,ValueB
FROM inserted
) new ON new.tableA_ID = tableA.ID
As with anything, test it to be sure.
Whether or not you should be doing this in a trigger is a long discussion.
Performance-wise, you're going to see better performance, in most circumstances, with the second query. The reason I can simply state that is that you're only looking at a single lookup for the UPDATE in the query where you update everything all at once. Whereas, the first query has to find the data to UPDATE, two times.
However, again, test this.
And yes, as #SMor says in the comments, why you need this as a trigger should absolutely be discussed. Triggers can be seriously misused and abused.

Convert working SELECT query into UPDATE query

In SSMS 2014 I have a working SELECT query and want to convert it to and UPDATE statement to update a field in the main table. I have tried and tried many solutions, each results in a different error.
I've managed to do simple UPDATE SET WHERE queries before, but this is a little more complex using derived tables in the WHERE clause. On Searching I found a JOIN solution but for me it does not like the RIGHT or JOIN and in that solution the SET was the last line and SSMS does not like that either so I getting a little confused now.
This is my working SELECT Statement that selects the correct SKU's:
SELECT
dbo.tblHKProducts.SKU_ID, dbo.tblHKProducts.SKU_Description,
dbo.tblHKProducts.SKU_Scan_Group
FROM
dbo.tblHKProducts
RIGHT OUTER JOIN
(SELECT
tblHKProducts_1.SKU_ID, tblHKProducts_1.SKU_Description,
dbo.ForceScanByDescriptions.FindDescription
FROM
dbo.tblHKProducts AS tblHKProducts_1
RIGHT OUTER JOIN
dbo.ForceScanByDescriptions ON tblHKProducts_1.SKU_Description = dbo.ForceScanByDescriptions.FindDescription
WHERE
(tblHKProducts_1.SKU_Description IS NOT NULL)
) AS derivedtbl_1 ON dbo.tblHKProducts.SKU_ID = derivedtbl_1.SKU_ID
I'm trying to do something like this, SKU_Scan_Group is a field in tblHKProducts:
UPDATE dbo.tblHKProducts
SET SKU_Scan_Group = N'Yes'
RIGHT OUTER JOIN
(SELECT
tblHKProducts_1.SKU_ID, tblHKProducts_1.SKU_Description,
dbo.ForceScanByDescriptions.FindDescription
FROM
dbo.tblHKProducts AS tblHKProducts_1
RIGHT OUTER JOIN
dbo.ForceScanByDescriptions ON tblHKProducts_1.SKU_Description = dbo.ForceScanByDescriptions.FindDescription
WHERE
(tblHKProducts_1.SKU_Description IS NOT NULL)
) AS derivedtbl_1 ON dbo.tblHKProducts.SKU_ID = derivedtbl_1.SKU_ID
Any help would be appreciated!
Thanks
Kev
This is quite simple, actually. This should work:
UPDATE P
SET P.SKU_Scan_Group = N'Yes'
-- SELECT P.SKU_ID, P.SKU_Description, P.SKU_Scan_Group
FROM dbo.tblHKProducts AS P
RIGHT JOIN (
SELECT P1.SKU_ID
, P1.SKU_Description
, FSBD.FindDescription
FROM dbo.tblHKProducts AS P1
RIGHT JOIN dbo.ForceScanByDescriptions AS FSBD
ON P1.SKU_Description = FSBD.FindDescription
WHERE P1.SKU_Description IS NOT NULL
) AS derivedtbl_1
ON P.SKU_ID = derivedtbl_1.SKU_ID;
P.S.
Start using aliases to reference tables your code might become quite hard to maintain later.

left join not showing null values

I need to find the items that exist in table A but not in table B. Now that would be really simple in MySQL doing a join like this
select * from A
left join B on A.key=B.key
where B.key is null
However for some reason this is not working in MSSQL. I have created the query without the where clause to see all the results and I only see matches, not null values. Do you have any idea why this is not working?
I know I can alternatively use "when not exists" but I want to know the reason as to why with a join is not working.
I am adding the code for your review
select Absences.CustomerID, b.*
from (
select * from openquery(JUAN_INTERFACE,'select cmp_wwn from Planet_Customers where i_outcome =4')) b
left join Absences on Absences.CustomerID = b.cmp_wwn
where Absences.Type = 3223
Your where clause is filtering out null values:
where Absences.Type = 3223
You are left-joining from the openquery subquery to Absences; and then filtering only rows that have a specific (non-null) value in an Absences column.
Did you mean to join the other way around, from Absenses to openquery?

Resources