I am querying two tables and joining them together on people's names. I am trying to produce all employees who have not filled out a form within the past month. The problem I am encountering is I am receiving an overlap of names when people list their short name (Joe rather than Joseph, or Mike rather than Michael). How can I still produce the list of people without overlap, even when they use their short names?
This is the query I have as of now:
SELECT DISTINCT ge.employeeNo,
(ge.firstName + ' ' + ge.lastName) AS empName,
ge.email
FROM dbo.hist_Employees ge
INNER JOIN dbo.ctrl_Sites cs ON ge.locationID = cs.ID
WHERE (ge.firstName + ' ' + ge.lastName) NOT IN
(SELECT sc.recordedBy
FROM GRSTOPS.dbo.hist_StopCard sc
INNER JOIN dbo.ctrl_Area a ON sc.area = a.ID
INNER JOIN dbo.ctrl_Site s ON a.site = s.ID
WHERE sc.recorded BETWEEN '10/01/2013' AND '10/30/2013'
AND s.code = 'gre')
AND cs.Abbreviation = 'gre'
AND ge.employmentStatus = 1
AND ge.primaryDept <> 3
It would be better not to join on peoples names as they are not unique.
You should join using a primary key like ID/employeeNo etc.
Related
I'm having an issue working with SQL data where once I have completed muptiple joins I am getting duplicate data.
Here is the code written for
SELECT RPPlannedLabor.PeriodHrs, RPPlannedLabor.StartDate, (RPAssignment.WBS1 + ' ' + PR.Name) AS 'WBS1', RPAssignment.WBS2, EM.FirstName, EM.LastName, EM.TKGroup, (EM.FirstName + ' ' + EM.LastName) AS 'Full Name'
FROM RPPlannedLabor
LEFT OUTER JOIN RPAssignment
ON RPPlannedLabor.AssignmentID = RPAssignment.AssignmentID
AND RPAssignment.WBS1 IS NOT NULL
LEFT OUTER JOIN EM
ON RPAssignment.ResourceID = EM.Employee
AND EM.Status = 'a'
LEFT OUTER JOIN PR
ON ((RPAssignment.WBS1 = PR.WBS1)
AND (ISNULL(RPAssignment.WBS2,0) = ISNULL(PR.WBS2,0))
AND (ISNULL(RPAssignment.WBS3,0) = ISNULL(PR.WBS3,0)))
AND PR.Sublevel = 'Y'
Any help would be greatly appreciated :)
I'd have to guess your isnull portions in the join is finding a bunch of null fields and cross joining, but thats just a guess. Data issues like this can't really be solved on a code help forum, best I can do is teach you to trouble shoot.
Run this and get the row count:
SELECT count(1)
FROM RPPlannedLabor
Run this
SELECT count(1)
FROM RPPlannedLabor
LEFT OUTER JOIN RPAssignment
ON RPPlannedLabor.AssignmentID = RPAssignment.AssignmentID
AND RPAssignment.WBS1 IS NOT NULL
Compare with first query...if count increase, your duplicate is on this first join.
Doesn't increase? Keep iterating, run this:
SELECT count(1)
FROM RPPlannedLabor
LEFT OUTER JOIN RPAssignment
ON RPPlannedLabor.AssignmentID = RPAssignment.AssignmentID
AND RPAssignment.WBS1 IS NOT NULL
LEFT OUTER JOIN EM
ON RPAssignment.ResourceID = EM.Employee
AND EM.Status = 'a'
Compare to your count above. Are there more records or is it the same? more records means this last join we added is causing them. If not...my guess is this here is causing the duplicates:
LEFT OUTER JOIN PR
ON ((RPAssignment.WBS1 = PR.WBS1)
AND (ISNULL(RPAssignment.WBS2,0) = ISNULL(PR.WBS2,0))
AND (ISNULL(RPAssignment.WBS3,0) = ISNULL(PR.WBS3,0)))
AND PR.Sublevel = 'Y'
If you are joining on fields with isnull functions, odds are there are nulls and potentially more than one...but I might be off as your data issue could be anywhere.
I have a problem I can't really figure out, even though I thought I had the solution.
I think this is DB2 SQL by the way.
I have a customer number and a country code (extracted from a string using SUBSTR) which I don't want to find in combination in a subquery, like so:
SELECT ku.orgnr AS customer ,
Substr(bu.bank_account_swiftadr,5,2) AS country
FROM db811.bet_utl bu
LEFT JOIN db811.henv_utl bh
ON bu.betaling_urn = bh.betaling_urn
LEFT JOIN db811.betaling_status bs
ON bu.betaling_status = bs.betaling_status
LEFT JOIN db811.kunde_orgnr ku
ON bu.kundenr = ku.kundenr
WHERE bu.kanal = 'N'
AND (ku.orgnr, Substr(bu.bank_account_swiftadr,5,2)) ;
Not in the results below
SELECT ku.orgnr AS customer ,
Substr(bu.bank_account_swiftadr,5,2) AS country ,
COUNT(*) AS numberof
FROM db811.bet_utl_hist bu
LEFT JOIN db811.kunde_orgnr ku
ON bu.kundenr = ku.kundenr
WHERE
and bu.kanal = 'N'
AND bu.betalingsdato > '2016-01-01'
GROUP BY ku.orgnr ,
substr(bu.bank_account_swiftadr,5,2);
This should work I though, but it seems to match on just one of them, and I need both to be true in order for me to exclude it with the NOT IN.
I assume I am missing something basic since I am quite new at this.
I have a query I'm writing, and it's nearly perfect, excepting one error I can't seem to control for.
SELECT Clients.client_id,
Clients.last_name + ', ' + Clients.first_name AS Client_Name,
Query3.team_id,
Query3.team_name,
Query2.CSW_Name,
Query1.Date_of_Service AS Last_Service_by_CSW,
Query.Tx_Start_Date AS Tx_Start_Date,
Query.Tx_End_Date AS Tx_End_Date
FROM Clients
LEFT OUTER JOIN
(SELECT TxPlus.client_id,
Max(TxPlus.start_date) AS Tx_Start_Date,
Max(TxPlus.end_date) AS Tx_End_Date
FROM TxPlus
GROUP BY TxPlus.client_id) Query ON Query.client_id = Clients.client_id
LEFT OUTER JOIN
(SELECT EmployeeClients.client_id,
Employees.last_name + ', ' + Employees.first_name AS CSW_Name
FROM EmployeeClients
INNER JOIN Employees ON EmployeeClients.emp_id = Employees.emp_id
WHERE EmployeeClients.case_manager = 1) Query2 ON Clients.client_id = Query2.client_id
LEFT OUTER JOIN
(SELECT ClientVisit.client_id,
Max(ClientVisit.rev_timeout) AS Date_of_Service
FROM ClientVisit
INNER JOIN EmployeeClients ON ClientVisit.emp_id = EmployeeClients.emp_id
GROUP BY ClientVisit.client_id,
EmployeeClients.case_manager,
ClientVisit.visittype_id
HAVING EmployeeClients.case_manager = 1
AND ClientVisit.visittype_id = 9) Query1 ON Clients.client_id = Query1.client_id
LEFT OUTER JOIN
(SELECT TeamClient.client_id,
Team.team_id,
Team.team_name
FROM TeamClient
INNER JOIN Team ON TeamClient.team_id = Team.team_id
WHERE TeamClient.primary_flag = 1) Query3 ON Clients.client_id = Query3.client_id
WHERE Clients.client_status LIKE 'Active'
The objective is to basically pull a client record, and show the dates for their Treatment Plan, their Primary Team Assignments, their case manager, and the most Community Support service there case manager provided for them.
Right now, with the code as it's written, I get all the correct information, EXCEPT the most recent Community Support date. This returns the most recent service done by ANYONE, not the Case Manager.
I'm certain its a very simple problem, but it's driving me up the wall.
You all are an invaluable resource, and I thank you in advance.
Well, without knowing what the data looks like, I can't be 100% certain that this is the answer, but I have a pretty good feeling about it. I believe that this is the query that is returning your, "Community Support Date". (It wasn't identified as clearly as I would have liked, but it looks to me like this is it.)
(SELECT ClientVisit.client_id,
Max(ClientVisit.rev_timeout) AS Date_of_Service
FROM ClientVisit
INNER JOIN EmployeeClients ON ClientVisit.emp_id = EmployeeClients.emp_id
GROUP BY ClientVisit.client_id,
EmployeeClients.case_manager,
ClientVisit.visittype_id
HAVING EmployeeClients.case_manager = 1
AND ClientVisit.visittype_id = 9) Query1 ON Clients.client_id = Query1.client_id
So what you're doing is creating a subset of the data in these two tables, joined by emp_id and grouped by client, case manager and visit type. Then you remove any groups that are not the case manager or visit type you want. But by this point, you've already selected your Max(ClientVisit.rev_timeout) AS Date_of_Service. I believe that if you change your HAVING clause into a WHERE clause (and thus filter before you group) you will get the results you're looking for.
EDIT:
(SELECT ClientVisit.client_id,
Max(ClientVisit.rev_timeout) AS Date_of_Service
FROM ClientVisit
INNER JOIN EmployeeClients ON ClientVisit.emp_id = EmployeeClients.emp_id
WHERE EmployeeClients.case_manager = 1
AND ClientVisit.visittype_id = 9
GROUP BY ClientVisit.client_id) Query1 ON Clients.client_id = Query1.client_id
Let me say first that I'm new to SQL, and learning much every day. With that said, here is my problem. I have a view that is already created (It shows revenue generated on equipment), but I need one more table added to it (Expenses against the equipment). When I try to add an inner join table, it create a bunch of duplicate views. Here is my original view (For the revenue portion of it):
SELECT
<removed, there are about 25 of them>
FROM
dbo.LRCON WITH (nolock)
INNER JOIN dbo.LRCONVIN WITH (nolock) ON dbo.LRCONVIN.ConId = dbo.LRCON.ConId
INNER JOIN dbo.LRBILCON WITH (nolock) ON dbo.LRBILCON.ConId = dbo.LRCONVIN.ConId AND dbo.LRBILCON.UntId = dbo.LRCONVIN.UntId
INNER JOIN dbo.LRBILITM WITH (nolock) ON dbo.LRBILITM.ParentItmId = dbo.LRBILCON.ItmId
INNER JOIN dbo.LRBIL WITH (nolock) ON dbo.LRBIL.BilId = dbo.LRBILCON.BilId
INNER JOIN dbo.LRCONTYP WITH (nolock) ON dbo.LRCONTYP.ConTypId = dbo.LRCON.ConTypId
INNER JOIN dbo.COLOOKUP AS C1 WITH (nolock) ON C1.Id = dbo.LRBILITM.ItmTyp
INNER JOIN dbo.COLOOKUP AS C2 WITH (nolock) ON C2.Id = dbo.LRCONTYP.ConTyp
INNER JOIN dbo.VHVIN WITH (nolock) ON dbo.VHVIN.UntId = dbo.LRCONVIN.UntId
WHERE
(dbo.LRBIL.Status = 647) AND (dbo.LRBILITM.ItmTyp <> 274)
I then try to add another join:
INNER JOIN dbo.SVSLS WITH (nolock) on dbo.SVSLS.UntId = dbo.LRCONVIN.UntId
with the select statement:
ROUND(dbo.SVSLS.AmtSubtotal + dbo.SVSLS.AmtSupplies + dbo.SVSLS.AmtDiagnostic + dbo.SVSLS.AmtTax1 + dbo.SVSLS.AmtTax2, 2) AS SvcAmtSale
... but it produces many, many rows of duplicates because it adds the detail of each expense to each row of my original table.
Original table:
https://dl.dropboxusercontent.com/u/81145403/orginal_table.jpg
After I add my new join/select:
https://dl.dropboxusercontent.com/u/81145403/failed_table.jpg
How do I fix this? At the end of the day, I just want to compare my revenue vs expenses on equipment over a date range. I really don't care to have the individual detail of the expenses, just a grand total is fine with me.
Is the SvcSaleAmt the revenue that you are interested in? And are the multiple detail rows separate entries on the same item? If you do not necessarily care about the individual details, you can GROUP the items together. In order to do this, you will need to get rid of the SlsId from your SELECT list, and add
GROUP BY CusId, CusName, BillId, ConId, Prd, ConTypId, ....., AmtCos, AmtGpm
Using all of the columns you have in your SELECT statement. Replace the ROUND() AS SvcSaleAmt with:
ROUND(SUM(dbo.SVSLS.AmtSubtotal + dbo.SVSLS.AmtSupplies + dbo.SVSLS.AmtDiagnostic + dbo.SVSLS.AmtTax1 + dbo.SVSLS.AmtTax2), 2) AS SvcSaleAmt
I have a stored procedure that uses this select statement:
SELECT dbo.VendorProgram.id,
dbo.VendorProgram.CODE,
dbo.Programs.ProgramName
+ '-' + dbo.Divisions.Division
+ '-' + dbo.Vendors.Source
+ '-' + dbo.Mediums.Medium
+ '-' + dbo.VendorProgram.content
AS SourceDetail,
dbo.Vendors.Source,
dbo.Programs.ProgramName,
dbo.Divisions.Division,
dbo.Mediums.Medium,
dbo.VendorProgram.content,
dbo.VendorProgram.url,
dbo.VendorProgram.cost,
dbo.VendorProgram.Notes,
dbo.VendorProgram.StartDate,
dbo.VendorProgram.EndDate
FROM dbo.Programs
RIGHT OUTER JOIN dbo.VendorProgram
ON dbo.Programs.id = dbo.VendorProgram.programID
LEFT OUTER JOIN dbo.Vendors
ON dbo.VendorProgram.vendorID = dbo.Vendors.mappingID
LEFT OUTER JOIN dbo.Divisions
ON dbo.VendorProgram.divisionID = dbo.Divisions.id
LEFT OUTER JOIN dbo.Mediums
ON dbo.VendorProgram.mediumID = dbo.Mediums.id
Basically we have a system that put together a code for a vendor. It is made up of 5 IDs pulled from 5 separate tables. Those tables have actual text, for a vendor's name, a type of medium, etc... that match to each ID. So far nothing truly ground breaking in use here I think.
What I need to do is be able to write a query that uses paramaters, in text, to search those 5 separate tables, and find all the "vendor mappings" that could match. I am still new in the SQL world so I am not quite sure what that query would look like.
As an example of how I want to search. I enter into my search form the text "Face" for the vendor field. I would then expect the query runs a select against the vendor table itself to first find all possible vendor IDs with "face" in the name. Then it would need to select all rows from the combined table that have any of those IDs in them.
Hopefully this makes sense, and is possible. As always thanks for any help.
SELECT vp.id, vp.CODE,
p.ProgramName + '-' + d.Division + '-' + v.Source + '-' + m.Medium + '-' + vp.content AS SourceDetail,
v.Source,
p.ProgramName,
d.Division,
m.Medium,
vp.content,
vp.url,
vp.cost,
vp.Notes,
vp.StartDate,
vp.EndDate
FROM dbo.Vendors v
LEFT OUTER JOIN dbo.VendorProgram vp vp.vendorID = v.mappingID
LEFT OUTER JOIN dbo.Programs p ON p.id = vp.programID
LEFT OUTER JOIN dbo.Divisions d ON vp.divisionID = d.id
LEFT OUTER JOIN dbo.Mediums m ON vp.mediumID = m.id
WHERE v.Name LIKE '%Face%'
add
WHERE dbo.Vendors.ID in
(select ID From dbo.Vendors where dbo.Vendors.Field LIKE '%'+ #QueryText + '%'
If you want only the rows related to your search, switch to inner joins (or include some where not nulls) and in your join to Vendors, include:
AND Vendor.VendorName LIKE #PassedInParam
Where #PassedInParam would be passed into your proc and would be your search string with a '%' on either side, ie '%face%'