SQL Update using Select statement - sql

I have to add a contacts name to an assignments table by querying the contacts table.
Contact table:
ID First_name Last_Name
-----------------------------------
1234 John Jones
9876 Mary Smith
Assignment table
ContactID Name
-----------------
1234
9876
Using this query I get
Subquery returned more than 1 value.
Query:
update A
set Name = (select distinct first_name + ' ' + last_name from contacts c join Assignments A on c.id = A.contact_id where A.contact_id = c.id)
from Assignments A
join contacts c on c.id = A.contact_id
where c.id = A.contact_id
What am I missing?

JOIN them directly, like so:
UPDATE a
SET a.Name = c.first_name + ' ' + c.last_name
FROM Assignments a
INNER JOIN Contacts c ON c.id = A.contact_id

Try
Update A
Set A.name = c.First_name + ' ' + c.Last_name
From Assignment A JOIN Contacts C ON A.ContactID = C.ID

No need for a subselect
UPDATE A
SET Name = c.first_name + ' ' + c.last_name
FROM Assignments A
JOIN contacts c
ON c.id = A.contact_id

try this
UPDATE a
SET a.Name = c.first_name + ' ' + c.last_name
FROM Assignments a
INNER JOIN Contacts c ON c.id = A.contact_id

Related

How to Automate Execute UPDATE Statement from CONCAT Output

I have an SQL query for building an UPDATE statement with CONCAT like this.
Example:
select top 10000
concat ('update customer set phone_number = ''',phone_number,
''' where id = ''',id,''';')
from (
select a.phone_number, c.id from customer c
join address a on c.id = a.customer_id
where c.phone_number is null
) as cust_phone;
Result:
update customer set phone_number = '628814232154' where id = '3';
update customer set phone_number = '62896631457' where id = '5';
Is possible making this UPDATE output to run automatically? I still newbie with SQL Programming.
Why build a string at all?
update c set phone_number = a.phone_number
from customer c
join address a on c.id = a.customer_id
where c.phone_number is null
If you’re desperate to have the TOP in there:
update u set phone_number = t.phone_number
from customer u
join
(
select top 10000 c.id, a.phone_number
from customer c join address a on c.id = a.customer_id
where c.phone_number is null
) t
on u.id = t.id
[assuming sql-server]
Your posted code is almost there if you want to go the Dynamic Sql route. You just need to concatenate the output of your query into a sql string, and execute it with Exec(#sql)
declare #sql nvarchar(max)
select #sql = #sql + concat ('update customer set phone_number = ''',phone_number,'''
where id = ''',id,''';',Char(10))
from (
select top 10000 a.phone_number, c.id from customer c
join address a on c.id = a.customer_id
where c.phone_number is null
) as cust_phone;
Exec(#sql)
You will want to move your top n filter into the subquery, as i did above.
try:
UPDATE customer
SET phone_number = (SELECT phone_number
FROM address
WHERE customer.id = address.customer_id)
WHERE phone_number is null;

Multiple joins into the same table (TSQL)

I'm needing rows from the Employee table that have null values in OwnerID field and GMID field.
SELECT b.FirstName + space(1) + b.LastName AS OwnerName,
c.FirstName + space(1) + c.LastName AS GeneralManager
FROM Store a
JOIN Employee b ON a.OwnerID = b.EmployeeID
JOIN Employee c ON a.GMID = c.EmployeeID
The query is working...but the store table has null values in the OwnerID and the GMID fields. What changes do I need to bring back the null rows also?
Update
This is the corrected query.
SELECT b.FirstName + space(1) + b.LastName AS OwnerName,
c.FirstName + space(1) + c.LastName AS GeneralManager
FROM Store a
LEFT JOIN Employee b ON a.OwnerID = b.EmployeeID
LEFT JOIN Employee c ON a.GMID = c.EmployeeID
https://learn.microsoft.com/en-us/sql/t-sql/queries/from-transact-sql?view=sql-server-2017
Use left join instead of join.
The LEFT JOIN keyword returns all records from the left table (table1), and the matched records from the right table (table2). The result is NULL from the right side, if there is no match.
Type of joins: See more here

Filter on Join but still return all rows

Im not sure exactly how to explain this. The best i can explain it is that i want to do something similar to a Left Join, only i want to return a subset of the main table matching criteria of the joined table, but still return all left joined rows. I hope that makes some sort of sense.
I have 4 tables:
Company
Services
ServicesTranslations
CompanyService
A Company can have many Services and a Service can have many Translations.
I want to filter on the ServiceTranslation table for a given search term.
The only way i can get this to work is in the SQL below, but i feel perhaps there is a better more cleaner way to do this, or is my solution ok?
DECLARE #defaultLanguage NVARCHAR(5)
SET #defaultLanguage = (SELECT LanguageCode FROM LANGUAGE WHERE IsDefault = 1)
SELECT
c.Id,
c.Name,
c.OrgNr,
c.UserId,
c.Address,
c.PostalArea,
c.County,
c.Country,
c.Description,
c.DescriptionFull,
c.Telephone,
c.Email,
c.Website,
c.IsApproved,
s.Id,
ISNULL(tr.Name, def.Name) Name
FROM Company c
INNER JOIN CompanyService cs on cs.CompanyId = C.Id
INNER JOIN Service s on s.Id = cs.ServiceId
LEFT OUTER JOIN ServiceTranslation tr
ON s.Id = tr.ServiceId AND tr.LanguageCode = #userLanguage
-- join default language of the service:
LEFT OUTER JOIN ServiceTranslation def
ON s.Id = def.ServiceId AND def.LanguageCode = #defaultLanguage
WHERE c.IsApproved = 1
AND
c.Id IN
(
SELECT c1.Id FROM Company c1
INNER JOIN CompanyService cs1 on cs1.CompanyId = c1.Id
INNER JOIN Service s1 on s1.Id = cs1.ServiceId
INNER JOIN ServiceTranslation tr1
ON s1.Id = tr1.ServiceId AND tr1.LanguageCode = #userLanguage
-- join default language of the service:
INNER JOIN ServiceTranslation def1
ON s1.Id = def1.ServiceId AND def1.LanguageCode = #defaultLanguage
AND s1.IsApproved = 1 AND ISNULL(tr1.Name, def1.Name) LIKE '%' + #searchQuery + '%'
)
Thanks in advance!
EDIT:
I think some clarification is required. Im not sure how to add the table data in a readable format so i have attached some images of the tables and desired results.
Company Table:
Service Table:
ServiceTranslation Table:
CompanyService Table:
Desired Results (#userLanguage = 'nb-NO' and #searchquery = 'Transport'):
There are two companies that have a Service with the word 'Transport' in. I want these two companies returned plus all their other services.
As you can see from the result image, im filter companies that have a matching service, but still want to return those matching companies and all of their services.
I hope this makes it a bit more clear :)
Using CTE:
;WITH Comps AS
(
SELECT DISTINCT c.CompanyId FROM CompanyService C
LEFT JOIN ServiceTranslation tr ON tr.ServiceId = C.ServiceId AND tr.LanguageCode = #userLanguage AND tr.Name LIKE '%' + #searchQuery + '%'
LEFT JOIN ServiceTranslation def ON def.ServiceId = C.ServiceId AND def.LanguageCode = #defaultLanguage AND def.Name LIKE '%' + #searchQuery + '%'
WHERE tr.ServiceId IS NOT NULL OR def.ServiceId IS NOT NULL
)
SELECT
c.Id,
c.Name,
c.OrgNr,
c.UserId,
c.Address,
c.PostalArea,
c.County,
c.Country,
c.Description,
c.DescriptionFull,
c.Telephone,
c.Email,
c.Website,
c.IsApproved,
s.Id,
def.Name
FROM Company c
INNER JOIN CompanyService cs on cs.CompanyId = C.Id
INNER JOIN Service s on s.Id = cs.ServiceId
INNER JOIN ServiceTranslation def ON def.ServiceId = s.Id AND def.LanguageCode = #defaultLanguage
INNER JOIN Comps CM ON CM.CompanyId = c.Id
WHERE c.IsApproved = 1 AND s.IsApproved = 1
OR with a subquery:
SELECT
c.Id,
c.Name,
c.OrgNr,
c.UserId,
c.Address,
c.PostalArea,
c.County,
c.Country,
c.Description,
c.DescriptionFull,
c.Telephone,
c.Email,
c.Website,
c.IsApproved,
s.Id,
def.Name
FROM Company c
INNER JOIN CompanyService cs on cs.CompanyId = C.Id
INNER JOIN Service s on s.Id = cs.ServiceId
INNER JOIN ServiceTranslation def ON def.ServiceId = s.Id AND def.LanguageCode = #defaultLanguage
INNER JOIN Comps CM ON CM.CompanyId = c.Id
WHERE c.IsApproved = 1 AND s.IsApproved = 1 AND c.Id IN
(
SELECT DISTINCT c.CompanyId FROM CompanyService C
LEFT JOIN ServiceTranslation tr ON tr.ServiceId = C.ServiceId AND tr.LanguageCode = #userLanguage AND tr.Name LIKE '%' + #searchQuery + '%'
LEFT JOIN ServiceTranslation def ON def.ServiceId = C.ServiceId AND def.LanguageCode = #defaultLanguage AND def.Name LIKE '%' + #searchQuery + '%'
WHERE tr.ServiceId IS NOT NULL OR def.ServiceId IS NOT NULL
)

SQL Insert doing conditional checking

I have written this SQL query that returns the users with first and last name if same name is found in two different databases database1 and database2, if the user's status is 'employee' in one of the tables in database1.
SELECT distinct
FirstName, LastName
FROM
database1.dbo.test1 a
JOIN
database1.dbo.test2 b ON b.id = a.id
JOIN
database1.dbo.test3 c ON a.id = c.id
JOIN
database2.dbo.test d ON a.firstname + ' ' + a.lastname = d.firstname + ' '+ d.lastname
WHERE
c.status = 'employee'
Now, I need to compare this first and last names I got using above query with the first and last name in database "database2" and if match is found I need to insert in column "isemployee" as yes. Can you please suggest how can I apply the condition to compare the names I got using above Select query and the names in database2 and insert in column "isemployee" of database2 if name match is found or condition is true.
You can use the code below...
UPDATE d SET isemployee = 'YES!'
FROM
database1.dbo.test1 a
join database1.dbo.test2 b on b.id = a.id
join database1.dbo.test3 c on a.id = c.id
join database2.dbo.test d
on a.firstname + ' ' + a.lastname = d.firstname + ' '+ d.lastname
where
c.status = 'employee'
All you need to do is to use your own query to update the column that you want, because the comparison already had been made
You could something like this using Exists
UPDATE d2
SET d2.isemployee = 1
FROM database2.dbo.test d2
WHERE EXISTS ( SELECT *
FROM database1.dbo.test1 a
JOIN database1.dbo.test2 b ON b.id = a.id
JOIN database1.dbo.test3 c ON a.id = c.id
WHERE c.status = 'employee'
AND a.firstname = d2.firstname
AND a.lastname = d2.lastname )

MSACCESS SQL Compare values in 2 tables

I have 2 tables; table A and B. My data looks as follows below. I'm trying to do 2 things:
How many times the Last Name and Zip in table A match the Last Name and Zip in table B?
If Last Name and Zip in Table A match Last Name and Zip in table B, how often do their phone numbers match?
Table A
Last Name..........Zip.....Phone
Tester..............00000....555555555
Tester..............00000....111111111
Test................11111.....99999999
Table B
Last Name..........Zip.....Phone
Tester..............00000....555555555
Tester..............00000....111111111
Test................11111.....99999999
This should give you the first answer
SELECT COUNT(A.Last Name) as namezipmatch
FROM A
INNER JOIN B ON A.LAST_NAME = B.LAST_NAME
WHERE
A.ZIP = B.ZIP
This should give you the second answer
SELECT COUNT(A.Last Name) as nameziphonematch
FROM A
INNER JOIN B ON A.LAST_NAME = B.LAST_NAME
WHERE
A.ZIP = B.ZIP AND A.PHONE = B.PHONE
Perhaps... Can't recall if access lets you count distinct.
SELECT count(Distinct B.Last_name + B.Zip) as CntLastZip,
count(Distinct C.Last_Name + C.Zip + C.Phone) as CntLastZipPhone
FROM TableA
LEFT JOIN tableB
ON A.Last_name = B.Last_Name
AND A.Zip = B.ZIP
LEFT JOIN tableC
ON A.Last_Name = C.Last-Name
AND A.Zip=C.Zip
AND A.Phone = C.Phone