MSACCESS SQL Compare values in 2 tables - sql

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

Related

LEFT OUTER JOIN WITH inner join with case in SQL DBMS

I have the following query
SELECT
A.WORKNR AS "WORK-nr",
UCASE(A.NAME) AS "NAME" ,
UCASE(A.ADRESS) AS "adress",
A.ZIPNR,
UCASE(A.ZIPADR) AS "zipadress",
A.NNR,
CASE
WHEN AO.ORG_REF IS NULL THEN 'OK'
ELSE 'NO '
END AS RESULT OF ORG ,
CASE
WHEN B.B = 1 THEN 'OK'
ELSE 'COME WITH ANOTHER NNR'
END AS COMPARE_RESULT
FROM
WORK.WORK_ADRESS A
LEFT JOIN
(SELECT
POSTNR, UCASE(STREET) AS STREET,
COUNT(DISTINCT NNR) AS B
FROM
WORK.WORK_ADRESS
GROUP BY
ZIPNR, UCASE(STREET)) B ON B.STREET = UCASE(A.STREET)
AND B.ZIPNR = ZIPNR
LEFT JOIN
(SELECT *
FROM WORK.ORGANISATION2) AO ON AO.WORK_REF = A.WORK_REF
AND AO.TILL >= CURRENT DATE
what I want is to add a JOIN to a third table ORG3 that contains the name for org genom
SELECT WORK.ORGANISATION2
INNER JOIN STYR.ORG2 ORG3 ON AO.ORG_REF3 = ORG3.ORG_REF
and get the column OR3.NAME as a separate column.
Can anyone help me? I am thankful

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 )

sql: how to use count for a particular column ,(or) to count a particular column by its field name

in my query i need a to count a particular column by its field name,
SELECT
C.INC_COUNT, MIN_X, MIN_Y, MAX_X, MAX_Y, B.STATE_ABBR,
B.STATE_NAME, B.LATITUDE, B.LONGITUDE, A.STATE, GEO_ID,
concat(A.LSAD_TRANS,' ' , A.NAME) DIST_NAME,
A.LSAD, GeometryType(SHAPE) GEO_TYPE, AsText(SHAPE) GEOM
from SHAPE_LAYERS A
join SHAPE_LAYER_STATE_DESC B
on ( A.state = B.state)
left outer join INC_DIST_SUMMARY_ALL C
on (C.SHAPE_GEO_ID = A. GEO_ID)
here i have to count by
B.STATE_NAME ,C.INC_COUNT
if exmple the field name nevada means i have to get all neveda value count and the C.INC_COUNT.
try this
SELECT count(C.INC_COUNT), MIN_X, MIN_Y, MAX_X, MAX_Y,
B.STATE_ABBR, count(B.STATE_NAME),B.LATITUDE,B.LONGITUDE,
A.STATE, GEO_ID, concat(A.LSAD_TRANS,' ' , A.NAME) DIST_NAME,
A.LSAD, GeometryType(SHAPE) GEO_TYPE, AsText(SHAPE) GEOM
from SHAPE_LAYERS A join SHAPE_LAYER_STATE_DESC B
on ( A.state = B.state)
left outer join INC_DIST_SUMMARY_ALL C
on (C.SHAPE_GEO_ID = A. GEO_ID)

How to find duplicate records in SQL?

I am trying to develop a query to insert unique records but am receiving the SQL Server Primary Key error for trying to insert duplicate records. I was able to insert some values with this query but not for this record (score_14).
So now I am trying to find duplicate record with the following query. The challenge is that my PK is based on 3 columns: StudentID, MeasureDate, and MeasureID--all from a different table not mentioned below.
But this only shows me count--instead I want to just return records with count > 1. How do I do that?
select count(a.score_14) as score_count, A.studentid, A.measuredate, B.measurename+' ' +B.LabelName
from [J5C_Measures_Sys] A
join [J5C_ListBoxMeasures_Sys] B on A.MeasureID = B.MeasureID
join sysobjects so on so.name = 'J5C_Measures_Sys'
join syscolumns sc on so.id = sc.id
join [J5C_MeasureNamesV2_Sys] v on v.Score_field_id = sc.name
where so.type = 'u' and sc.name = 'score_14' and a.score_14 is not null
AND A.STUDENTID IS NOT NULL AND A.MEASUREDATE IS NOT NULL AND B.MEASURENAME IS NOT NULL
--and count(a.score_14)>1
group by a.studentid, a.measuredate, B.measurename, B.LabelName, A.score_14
having count(a.score_14) > 1
Beth is correct - here's my re-write of your query:
SELECT a.studentid, a.measuredate, a.measureid
from [J5C_Measures_Sys] A
GROUP BY a.studentid, a.measuredate, a.measureid
HAVING COUNT(*) > 1
Previously:
SELECT a.studentid, a.measuredate, a.measureid
from [J5C_Measures_Sys] A
join [J5C_ListBoxMeasures_Sys] B on A.MeasureID = B.MeasureID
join sysobjects so on so.name = 'J5C_Measures_Sys'
AND so.type = 'u'
join syscolumns sc on so.id = sc.id
and sc.name = 'score_14'
join [J5C_MeasureNamesV2_Sys] v on v.Score_field_id = sc.name
where a.score_14 is not null
AND B.MEASURENAME IS NOT NULL
GROUP BY a.studentid, a.measuredate, a.measureid
HAVING COUNT(*) > 1
you need to take A.score_14 out of your group by clause if you want to count it

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.