SQL Insert doing conditional checking - sql

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 )

Related

SQL IN "Too many values"

I have a problem I want to get all of the DISTINCT CLIENTIDs in my LCMINV table in which the CLIENTID is in LAAPPL's CLIENTID and LACOBORW's COBORWID and also the APPLICATION STATUS is either 'PEN' OR 'REC'.
Here is my table:
++++++++++++++++++++++++++++++++++++++++++++
+ LAAPPL + LACOBORW + LCMINV +
++++++++++++++++++++++++++++++++++++++++++++
+ CLIENTID + APPLNO + CLIENTID +
+ APPLNO + COBORWID + +
+ STATUS + + +
++++++++++++++++++++++++++++++++++++++++++++
Here is my SQL Query I've done so far:
SELECT DISTINCT(CLIENTID)
FROM LCMINV
WHERE CLIENTID
IN (SELECT CLIENTID, COBORWID
FROM LAAPPL
LEFT OUTER JOIN LACOBORW ON LACOBORW.APPLNO = LAAPPL.APPLNO
WHERE STATUS = 'PEN' OR STATUS = 'REC')
Can it be done in one query or do I need separate queries? I tried my query above an I am getting an error "Too many values"
I would probably use a CTE to break the query up into smaller parts, and then use INNER JOINs to combine the tables. Since You query LAAPPL, I put both columns used into a single subquery, and then join on each column in the next CTE.
It would look something like this:
WITH CTE_LAAPPL AS
(
SELECT
CLIENTID
,APPLNO
FROM LAAPPL
WHERE STATUS IN ('PEN','REC')
)
,CLIENTIDs AS
(
SELECT DISTINCT
l.COBORWID AS CLIENTID
FROM CTE_LAAPPL c
INNER JOIN LACOBORW l ON l.APPLNO = c.APPLNO
UNION
SELECT DISTINCT
l.CLIENTID
FROM CTE_LAAPPL c
INNER JOIN LCMINV l ON l.CLIENTID = c.CLIENTID
)
SELECT
c.CLIENTID
,c.NAME
FROM LCCLIENT c
INNER JOIN CLIENTIDs i ON i.CLIENTID = c.CLIENTID
ORDER BY NAME
I think you just want:
SELECT DISTINCT i.CLIENTID
FROM LCMINV i
WHERE i.CLIENTID IN (SELECT a.CLIENTID
FROM LAAPPL a JOIN
LACOBORW c
ON c.APPLNO = a.APPLNO
WHERE a.STATUS IN ('PEN', 'REC')
);
I'm not really sure why you are joining in LACOBORW. You can probably remove that logic.
I would recommend left joins to get the data you need. Unfortunately, your question 3 does not seem to fit your model because your LCMINV table does not seem to have an id that matches to another table and I cannot understand where LCMINV.CLIENTID should be related to in another context. This works in MSSQL - cannot be sure about Oracle.
--this statement will give you all the names that have a status in the where clause
--you will receive NULL if there is no Co-BorrowerID
select
a.name
, b.applno
, b.status
, c.coborwid
from
lcclient a left join
laapl b on a.clientid = b.clientid left join
lacoborw c on b.applno = c.applno
where
b.status in ('PEN', 'REC')
order by
a.name

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;

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

SQL Update using Select statement

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

Is it possible to use conditional statements such as if/then/when like this in SQL?

I have an SQL query that has an id field - think of it as a foreign key. I need to make a desicion based on the value of this id field such that:
If the value is less then 3100, run a nested fetch from table B.
If the value is greater then 3100, run a nested fetch from a table C.
The statement looks like this:
Select a.ID, a.SN, a.User_Ident,
(select b.first_name from b where b.ident = a.User_Ident) as 'First Name',
(select b.last_name from b where b.ident = a.User_Ident) as 'Last Name',
from a
where ...
What I would like to accomplish is something like this:
Select a.ID, a.SN, a.User_Ident,
when a.User_Ident > 3100 then
(select b.first_name from b where b.ident = a.User_Ident) as 'First Name',
(select b.last_name from b where b.ident = a.User_Ident) as 'Last Name'
else
(select c.name from c where c.ident = a.User_Ident) as 'Name'
from a
where ....
Is this possible?
UPDATE: Your answers suggested I use left joins. My query already contains several left outer joins, so I don't know how this would work. Here is the complete query:
select
A.Ident,
A.Serial_Number,
A.Category_Ident,
C.Description as Category,
A.Purchase_Order,
A.Manufacturer_Ident,
M.Description as Manufacturer,
A.Hardware_Model,
A.Processor_Quantity,
A.Processor_Speed_Hertz,
A.Memory_Installed_Bytes,
A.Memory_Maximum_Bytes,
A.Memory_Slots_Used,
A.Memory_Slots_Total,
A.Storage_Capacity_Bytes,
A.Video_Memory_Bytes,
A.Screen_Size_Diagonal_Inches,
A.Software_Ident,
S.Software_Title,
A.Account_Ident,
T.Description as Account,
A.User_Ident,
(select Q.dbo.P.user_name from Q.dbo.P where Q.dbo.P.ident = A.User_Ident) as 'User Name',
(select Q.dbo.P.first_name from Q.dbo.P where Q.dbo.P.ident = A.User_Ident) as 'First Name',
(select Q.dbo.P.last_name from Q.dbo.P where Q.dbo.P.ident = A.User_Ident) as 'Last Name',
(select Q.dbo.R.description from Q.dbo.R where Q.dbo.R.ident = (select Q.dbo.P.rank from Q.dbo.P where Q.dbo.P.ident = A.User_Ident)) as 'Rank',
(select Q.dbo.P.phone from Q.dbo.P where Q.dbo.P.ident = A.User_Ident) as 'Phone',
(select Q.dbo.P.smtp_address from Q.dbo.P where Q.dbo.P.ident = A.User_Ident) as 'Email',
(select Q.dbo.O.description from Q.dbo.O where Q.dbo.O.ident = (select Q.dbo.P.organization_ident from Q.dbo.P where Q.dbo.P.ident = A.User_Ident)) as 'Organization',
(select Q.dbo.L.description from Q.dbo.L where Q.dbo.L.ident = (select Q.dbo.P.location_ident from Q.dbo.P where Q.dbo.P.ident = A.User_Ident)) as 'Location',
A.Disposition_Ident,
D.Description as Disposition,
A.Notes,
A.Updated,
A.UpdatedBy,
A.Label,
A.Scanned,
S.Licensed
FROM Assets
left outer join C on A.Category_Ident = C.Ident
left outer join M on A.Manufacturer_Ident = M.Ident
left outer join S on A.Software_Ident = S.Ident
left outer join T on A.Account_Ident = T.Ident
left outer join D on A.Disposition_Ident = D.Ident
WHERE ((T.Description like '%' + #Account + '%') or (A.Account_Ident like '%' + #Account + '%'))
order by Serial_Number
Many ways to skin a cat, but I think this approach is worth a try, using a UNION to combine the results of the 2 different conditions (1 query joined to b for ids > 3100, and another query joined to c for ids <= 3100).
You have to return the same fields (you can't as you indicated you wanted), return 1 "name" field when looking at c when you return 2 fields for the b condition. Hence, in this example, when you join to c, it returns "name" as First Name, and returns a blank Last Name value.
Select a.ID, a.SN, a.User_Ident, b.first_name AS 'First Name', b.last_name AS 'Last Name'
FROM a
JOIN b ON a.User_Ident = b.ident
WHERE (a.User_Ident > 3100)
AND (......)
UNION ALL
Select a.ID, a.SN, a.User_Ident, c.name AS 'First Name', '' AS 'Last Name'
FROM a
JOIN c ON a.User_Ident = c.ident
WHERE (a.User_Ident <= 3100)
AND (......)
I'd accomplish this with two left joins and a case statement:
select a.field1,
case when b.lastname is not null then b.firstname else c.firstname end,
case when b.lastname is not null then b.lastname else c.larstname end
from table1 a
left join table2 b
on a.id = b.id
left join table3 c
on a.id = c.id
Note I used lastname is null filed in both case staments, becasue tyou probably don;t want the first name form one table and the last name form the other and lastname is less likely to be null than the firstname in the actual table.
Union would work(beat me there), or you could use an inline function as well. Like the others have said you must return same set of fields.
A slight variation on HLGEM's answer
select a.field1,
case when b.lastname is not null then b.firstname else c.firstname end,
case when b.lastname is not null then b.lastname else c.larstname end
from table1 a
left join table2 b
on a.User_Ident > 3100 AND a.id = b.id
left join table3 c
on a.User_Ident <= 3100 AND a.id = c.id
CASE can only return a column, not a row, and you can't correlate queries into it afaik. And no matter what, a result set must have a static amount of columns.
I think what you would want would be a result set where if the First Name or Last Name was filled out the Name was null.
a.ID | a.SN | Name | First Name | Last Name
1 | # | Name | null | null
2 | # | null | John | Doe
My take on the outer join solution is:
SELECT
a.id
,a.ssn
,a.user_ident
,case when a.user_ident <= 3100 then c.name else b.lastname end LastName
,case when a.user_ident <= 3100 then '' else b.firstname end FirstName
from a
left outer join b
on b.ident = a.user_ident
left outer join c
on c.ident = a.user_ident
A query cannot vary the number of columns returned (at least not in any system I'm familiar with), so if you have a "case C" situation and only have Name, I would return it as LastName and set FirstName to the empty string. This could be made a NULL, if that fits your application better.