Welcome to Dream.In.Code
Getting Help is Easy!

Join 136,825 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 1,879 people online right now. Registration is fast and FREE... Join Now!




SQL Query Help - Join Issues.

 
Reply to this topicStart new topic

SQL Query Help - Join Issues.

gymratz
29 Sep, 2008 - 01:46 PM
Post #1

D.I.C Head
**

Joined: 18 Oct, 2007
Posts: 72


My Contributions
Editing to make more clear...
To summarize in english.
Each client will have multiple people assigned to it, of which I need to display a few.
Each client will have multiple engagements. We are interested in the newest of each distinct engagement (of which there are like 5 types).
Each row in the gridview will represent an engagement that belongs to a client that the user looking at it is part of.
Some things in the row are client level (so will be the same in each row) some are engagement level (so will be different in each row).

CODE
Select EmpMe.Full_Name as Me, EmpL.Full_Name as Lead, EmpA.Full_Name as Associate, C.Name, E.Classification,
E.End_Quarter, E.End_Year, E.Data_In, E.Pts_Sent, E.RFD_Sent, E.RR_Assigned, E.Pending_C_Response,
datediff(d, getdate(), e.data_in) as Days_Pending, E.Memo
From Engagements as E
INNER JOIN Clients as C on C.ID = E.Client_ID
INNER JOIN Rep_Client as RC on C.ID = RC.Client_ID
INNER JOIN Rep_Client as RCA on C.ID = RCA.Client_ID
INNER JOIN Rep_Client as RCL on C.ID = RCL.Client_ID
INNER JOIN Employees as EmpMe on EmpMe.ID = RC.Emp_ID AND EmpMe.ID = '18'
INNER JOIN Employees as EmpA on EmpA.ID = RCA.Emp_ID AND RCA.Position = 'Associate'
INNER JOIN Employees as EmpL on EmpL.ID = RCL.Emp_ID AND RCL.Position = 'Lead Verifier'
WHERE E.Reports_Out is NULL


Problems:
If there are no employees for a client with position Associate or Lead Verifier, the row doesn't return at all. Need to fix this.

Things still left to do:
Each C.Name can have multiple E.Classifications.
I want to grab the most recent of each Identical E.Classification.

Example.
Class 1 - 4q 2008
Class 2 - 4q 2008
Class 3 - 4q 2008
Class 3 - 1q 2007
Class 1 - 1q 2009
This should return three rows.
Class 1 - 1q 2009 (most recent)
Class 2 - 4q 2008 (Only one)
Class 3 - 4q 2008 (most recent)

To do this I'd need to grab max YEAR and then max QTR (since number is first it will grab 4q as highest)

For each of these rows I need the following: E.Classification,
E.End_Quarter, E.End_Year, E.Data_In, E.Pts_Sent, E.RFD_Sent, E.RR_Assigned, E.Pending_C_Response,
datediff(d, getdate(), e.data_in) as Days_Pending, E.Memo

Finally I need to find the max() of a date from another table Touch_Points - this date is applied at the client level so will be the same for each engagement.

Any help with existing problem or adding in additional parts mentioned would be greatly appreciated.


This post has been edited by gymratz: 29 Sep, 2008 - 03:34 PM
User is offlineProfile CardPM
+Quote Post

PsychoCoder
RE: SQL Query Help - Join Issues.
29 Sep, 2008 - 02:09 PM
Post #2

using DIC.Core;
Group Icon

Joined: 26 Jul, 2007
Posts: 8,997



Thanked: 125 times
Dream Kudos: 8625
Expert In: VB, VB.Net, C#, SQL, ASP, ASP.Net, Web Development, HTML, CSS, Win32 API, Javascript, mySQL, J#, Boo.Net

My Contributions
Change your JOIN type. An INNER JOIN will only return results if there's a match in both tables. A LEFT OUTER JOIN will return all the rows from the first table, even if there are no matches in the second table. A RIGHT OUTER JOIN will return all the rows from the second table, even if there are no matches in the first table.

Here's a pretty good article on JOINS In MSSQL Hope that helps smile.gif

Also, I'm moving this to the ASP.NET forum smile.gif
User is offlineProfile CardPM
+Quote Post

gymratz
RE: SQL Query Help - Join Issues.
29 Sep, 2008 - 02:18 PM
Post #3

D.I.C Head
**

Joined: 18 Oct, 2007
Posts: 72


My Contributions
QUOTE(PsychoCoder @ 29 Sep, 2008 - 03:09 PM) *

Change your JOIN type. An INNER JOIN will only return results if there's a match in both tables. A LEFT OUTER JOIN will return all the rows from the first table, even if there are no matches in the second table. A RIGHT OUTER JOIN will return all the rows from the second table, even if there are no matches in the first table.

Here's a pretty good article on JOINS In MSSQL Hope that helps smile.gif

Also, I'm moving this to the ASP.NET forum smile.gif


I tried using LEFT OUTER JOIN as that is the one that I thought I needed. However it has the opposite problem of returning too many results.
Let me try to explain.

There are only 3 records total so the max rows I should ever see are 3.
With INNER JOIN I only see 2 because one row doesn't have one of those last two fields (Associate or Lead Verifier).
If I change this to OUTER LEFT JOIN I get 41 rows.
It's like it's taking the left outer of that specific part
LEFT OUTER JOIN Employees as EmpA on EmpA.ID = RCA.Emp_ID AND RCA.Position = 'Associate'

But what I really want to do is left outer join that inner join with the previous joins... Does that make any sense?

CODE
Select EmpMe.Full_Name as Me, EmpL.Full_Name as Lead, EmpA.Full_Name as Associate, C.Name, E.Classification,
E.End_Quarter, E.End_Year, E.Data_In, E.Pts_Sent, E.RFD_Sent, E.RR_Assigned, E.Pending_C_Response,
datediff(d, getdate(), e.data_in) as Days_Pending, E.Memo
From Engagements as E
INNER JOIN Clients as C on C.ID = E.Client_ID
INNER JOIN Rep_Client as RC on C.ID = RC.Client_ID
INNER JOIN Rep_Client as RCA on C.ID = RCA.Client_ID
INNER JOIN Rep_Client as RCL on C.ID = RCL.Client_ID
INNER JOIN Employees as EmpMe on EmpMe.ID = RC.Emp_ID AND EmpMe.ID = '18'
LEFT OUTER JOIN(
INNER JOIN Employees as EmpA on EmpA.ID = RCA.Emp_ID AND RCA.Position = 'Associate'
INNER JOIN Employees as EmpL on EmpL.ID = RCL.Emp_ID AND RCL.Position = 'Lead Verifier')
WHERE E.Reports_Out is NULL


That is probably more accurately describing what I am trying to do - but obviously doesn't work (that just throws an error).
User is offlineProfile CardPM
+Quote Post

PsychoCoder
RE: SQL Query Help - Join Issues.
29 Sep, 2008 - 02:23 PM
Post #4

using DIC.Core;
Group Icon

Joined: 26 Jul, 2007
Posts: 8,997



Thanked: 125 times
Dream Kudos: 8625
Expert In: VB, VB.Net, C#, SQL, ASP, ASP.Net, Web Development, HTML, CSS, Win32 API, Javascript, mySQL, J#, Boo.Net

My Contributions
Did you try a RIGHT OUTER JOIN?
User is offlineProfile CardPM
+Quote Post

gymratz
RE: SQL Query Help - Join Issues.
29 Sep, 2008 - 02:40 PM
Post #5

D.I.C Head
**

Joined: 18 Oct, 2007
Posts: 72


My Contributions
That returns 48 rows, lol.
Changing from inner, to outer left or outer right seems to affect the EmpA.ID = RCA.Emp_ID - but does not seem to affect the way that the join as a whole gets joined with the others in the query.
User is offlineProfile CardPM
+Quote Post

baavgai
RE: SQL Query Help - Join Issues.
29 Sep, 2008 - 03:35 PM
Post #6

Dreaming Coder
Group Icon

Joined: 16 Oct, 2007
Posts: 2,040



Thanked: 106 times
Dream Kudos: 475
Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua

My Contributions
First, sanity check, the count should be no more than
CODE

Select count(*) From Engagements as E WHERE E.Reports_Out is NULL


On second thought, no more that this:
CODE

Select count(*)
    From Engagements as E
        INNER JOIN Clients as C on C.ID = E.Client_ID
    WHERE E.Reports_Out is NULL


With that in mind, we start here:
CODE

Select
        NULL as Me,
        NULL as Lead,
        NULL as Associate,
        C.Name,
        E.Classification,
        E.End_Quarter,
        E.End_Year,
        E.Data_In,
        E.Pts_Sent,
        E.RFD_Sent,
        E.RR_Assigned,
        E.Pending_C_Response
    From Engagements as E
        INNER JOIN Clients as C on C.ID = E.Client_ID
    WHERE E.Reports_Out is NULL



Now add in one of your names. Let's use a subquery
CODE

Select
        NULL as Me,
        EmpL.Full_Name as Lead,
        NULL as Associate,
        C.Name,
        E.Classification,
        E.End_Quarter,
        E.End_Year,
        E.Data_In,
        E.Pts_Sent,
        E.RFD_Sent,
        E.RR_Assigned,
        E.Pending_C_Response
    From Engagements as E
        INNER JOIN Clients as C on C.ID = E.Client_ID
        LEFT OUTER JOIN (
            select a.Client_ID as ID, b.Full_Name
                from Rep_Client a
                    inner join Employees b on b.ID = a.Emp_ID
                where a.Position = 'Lead Verifier'
        ) EmpL on C.ID = EmpL.ID
    WHERE E.Reports_Out is NULL


There is a fundamental assumption here, there we're only going to get one employee per clientId. If that's not the case, you'll get more than you want.

If this looks good, then add in the other two. If it's not working, analyize the sub queries on their own. e.g.
CODE

select a.Client_ID, count(a.Emp_ID) as countA, count(distinct a.Emp_ID) as countB
    from Rep_Client a
    where a.Position = 'Lead Verifier'
    group by a.Client_ID


CountA should equal CountB. If it doesn't, then assumptions about you data may be off.

Hope this helps.


User is offlineProfile CardPM
+Quote Post

gymratz
RE: SQL Query Help - Join Issues.
29 Sep, 2008 - 04:17 PM
Post #7

D.I.C Head
**

Joined: 18 Oct, 2007
Posts: 72


My Contributions
Actually the only time I was counting anything was just to show that it wasn't returning how many records I knew where there.

Here is my new code thanks to you.
CODE
Select
        EmpMe.Full_Name as Me,
        EmpL.Full_Name as Lead,
        EmpA.Full_Name as Associate,
        C.Name,
        E.Classification,
        E.End_Quarter,
        E.End_Year,
        E.Data_In,
        E.Pts_Sent,
        E.RFD_Sent,
        E.RR_Assigned,
        E.Pending_C_Response,
        datediff(d, getdate(), e.data_in) as Days_Pending,
        E.Memo
    From Engagements as E
        INNER JOIN Clients as C on C.ID = E.Client_ID
        INNER JOIN (
            select a.Client_ID as ID, b.Full_Name
                from Rep_Client a
                    inner join Employees b on b.ID = a.Emp_ID
                where a.Emp_ID = '18'
        ) EmpMe on C.ID = EmpMe.ID
        LEFT OUTER JOIN (
            select a.Client_ID as ID, b.Full_Name
                from Rep_Client a
                    inner join Employees b on b.ID = a.Emp_ID
                where a.Position = 'Lead Verifier'
        ) EmpL on C.ID = EmpL.ID
        LEFT OUTER JOIN (
            select a.Client_ID as ID, b.Full_Name
                from Rep_Client a
                    inner join Employees b on b.ID = a.Emp_ID
                where a.Position = 'Associate'
        ) EmpA on C.ID = EmpA.ID
    WHERE E.Reports_Out is NULL


Thise code actually satisfies almost all of what I need. I realized that some of the things I was asking for aren't needed due to policy (no two engagements of the same name can be going at the same time, thus only one should have a reports_out as NULL)

One last thing I need to add.
I need to add the following and hoping to get one more example to help teach me why I can't figure this out on my own.

LEFT OUTER JOIN (Select MAX(DATE) from Onsite_Testing_Visits) WHERE Onsite_Testing_Visits.Client_ID = (client ID of the engagement)

I'm trying to add that in there. This is related to the client level. Does this make enough sense that you can help one more time?

Thanks much!
User is offlineProfile CardPM
+Quote Post

baavgai
RE: SQL Query Help - Join Issues.
29 Sep, 2008 - 04:26 PM
Post #8

Dreaming Coder
Group Icon

Joined: 16 Oct, 2007
Posts: 2,040



Thanked: 106 times
Dream Kudos: 475
Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua

My Contributions
Perhaps something like this:
CODE

LEFT OUTER JOIN (
    Select Client_ID, MAX(DATE) as MaxDate from Onsite_Testing_Visits group by Client_ID
) otv on otv.Client_ID = E.Client_ID


User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic
Time is now: 12/3/08 03:32PM

Live Help!

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month