How to Automate Execute UPDATE Statement from CONCAT Output - sql

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;

Related

Count with exists in SQL

Why is this query not returning the count of the results? How do I get it to show the count
SELECT COUNT (*) AS MWith
FROM member m
JOIN Channel mc ON mc.MemberID = m.id
JOIN Client c ON c.id = m.clientid
JOIN packages p ON p.id = m.packageid
WHERE Enroll > '2018'
AND EXISTS (
SELECT * FROM
activity a
WHERE a.memberid = m.id
AND a.code IN ('785', 'a599')
)
GROUP BY m.id;
OUTPUT
MWith
1
1
1
The empty set is because of the clause group by .
The workarounds are:
Remove a GROUP BY, because m.id anyway is not part of the output
Use GROUP BY ALL
An original example:
SELECT COUNT(*) AS MWith
FROM member m
JOIN Channel mc
ON mc.MemberID = m.id
JOIN Client c
ON c.id = m.clientid
JOIN packages p
ON p.id = m.packageid
WHERE Enroll > '2018'
AND EXISTS
(
SELECT *
FROM activity a
WHERE a.memberid = m.id
AND a.code IN ( '785', 'a599' )
)
-- GROUP BY m.id;
Other, simpler examples to show a difference:
-- returns an empty resultset
SELECT COUNT(*) FROM sys.databases
WHERE 1=0
GROUP BY name
-- returns: a single row with 0
SELECT COUNT(*) FROM sys.databases
WHERE 1=0
-- Another example with GROUP BY ALL
-- it returns one row per grouped value, with expected count = 0
SELECT COUNT(*) FROM sys.databases
WHERE 1=0
GROUP BY ALL name

Left join to a table which may or not contain the data

I have the following tables : client and shop.
They have the following columns :
Client : Id, Name, Surname, Email
Shop : Id, Name, ClientId
ClientId is a foreign key to table Client.
I need to do a search based on the name AND surname OR Email and if there is any entry in the Shop table then return it
but should not return the Id passed as parameter.
I have tried using a left join as follows but this does not work:
select *
from Client c
left join Shop s
on c.Id = s.ClientId
where c.Name = 'abc'
and c.Surname = 'xyx'
and c.Id != Id
or c.Email = 'ab#cde.com'
and c.Id != Id
But this is not returning me the correct data.
For example, I want to seach the name Jon and surname Sam with email
jon#samy.com and clientId = 201.
So the request should return me all client having the name Jon and surname Sam or having email jon#samy.com
and if there is any entry with these details in the table Shop return it but excluding client with Id 201.
I would also like to convert this SQL to LinQ.
Any idea what is wrong with my request?
I am not sure if I understood the requirement completely. I am writing 2 queries. One of these should work in your case
If you want to exclude shop entries of the Id but want client entries
SELECT * FROM Client c
LEFT JOIN (SELECT * FROM Shop WHERE ClientId != Id) s ON c.Id = s.ClientId
WHERE (c.Name = 'abc' AND c.Surname = 'xyx') OR (c.Email = 'ab#cde.com')
If you want to exclude client entries
SELECT * FROM Client c
LEFT JOIN Shop s ON c.Id = s.ClientId
WHERE (c.Name = 'abc' AND c.Surname = 'xyx' AND c.Id != Id) OR (c.Email = 'ab#cde.com' AND c.Id != Id)
If it works, then let me know. I will help you with LINQ query. But try to write it yourself.
use inner join instead left join and use or condition and add union as you want data from client if no data in shop
select c.*
from Client c
inner join Shop s
on c.Id = s.ClientId
where c.Name = 'abc'
or c.Surname = 'xyx'
or c.Email = 'ab#cde.com'
union
select * from Client c
where c.Name = 'abc'
or c.Surname = 'xyx'
or c.Email = 'ab#cde.com'
Seems like you need to do an EXISTS rather than a LEFT JOIN as there could be a client appearing in different shops:
select *
from Client c
where exists(
select * from Shop s
where c.Id = s.clientid
)
and c.Name = 'Jon'
and c.Surname = 'Sam'
and c.Id <> 201
If you insist on LOJ:
select *
from Client c
left outer join Shop s
on c.Id = s.ClientId
where s.Id is not null
and c.Name = 'Jon'
and c.Surname = 'Sam'
and c.Id <> 201
LINQ:
var searchResult = from c in clients
where shops.Any(s => s.ClientId == c.Id)
&& c.Name.Equals("Jon")
&& c.Surname.Equals("Sam")
&& c.Id != 201
select c;

Update a column separated by comma for multiple values?

I have following table Userinfo_attarea:
id employee_id area_id
182521 4391 2
182522 4391 3
Personnel_area:
id areaid
1 Area Name
2 PROJECT80
3 PROJECT69
When i update it works fine foe single value but i need a column with multiple values separeted by comma as mentioned below
Expected Output:
areaname
PROJECT80,PROJECT69
i am using following query for update
UPDATE employee
SET employee.areaname = p.areaname
FROM employee join userinfo u
on u.badgenumber=employee.emp_reader_id join userinfo_attarea ua on ua.employee_id=u.userid join personnel_area p on ua.area_id=p.id
JOIN inserted I ON u.userid= I.employee_id
Thanks in advance...
You can try this :
Update E set areaname = T.areaname from #Employee E
Inner Join
(
Select employee_id,STUFF((SELECT ', ' + CAST(areaid AS VARCHAR(10)) [text()]
FROM (
Select U.employee_id,P.areaid from #Userinfo_attarea U
Inner Join #Personnel_area P on U.area_id = P.id
) B
WHERE employee_id = A.employee_id
FOR XML PATH(''), TYPE)
.value('.','NVARCHAR(MAX)'),1,2,' ') areaname from
(
Select U.employee_id,P.areaid from #Userinfo_attarea U
Inner Join #Personnel_area P on U.area_id = P.id
) A
GROUP BY employee_id
) T on T.employee_id = E.id
Working demo

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 )

Single Line separated records in SQL SERVER Query result

I had a query that returned multiple rows from a table. Then I converted that query to this one:
;with mycte as
(select s.FirstName + ' ' + s.LastName as Name from ClientStaff cs
left outer join Staff s on s.Id = cs.StaffId
left outer join GeneralStatus gs on gs.Id = s.StatusId
where cs.ClientId = #clientId and gs.Name = 'Active')
select #staff = (select distinct staff = REPLACE(REPLACE(REPLACE((select Name AS [data()] FROM mycte a
order by a.Name for xml path),'</row><row>',', '),'</row>',''),'<row>','') from mycte b)
It returns those rows in a single comma-separated row.
Now I don't want comma-separated values, instead I want single-line-separated values.
Can anyone tell me if it is possible or not?
Thanks in advance.
declare #staff varchar(max)
;with mycte as
(
select distinct s.FirstName + ' ' + s.LastName as Name
from ClientStaff cs
left outer join Staff s on
s.Id = cs.StaffId
left outer join GeneralStatus gs on
gs.Id = s.StatusId
where cs.ClientId = #clientId and gs.Name = 'Active'
)
select #staff = isnull(#staff + char(13), '') + Name
from mycte b
print #staff