Showing posts with label multiple. Show all posts
Showing posts with label multiple. Show all posts

Wednesday, March 21, 2012

Mixing INNER and OUTER joins

I've encountered this problem multiple times in the past and I have a solution but wonder if there might be a more elegant method of achieving the same result...

Take the following example:

SELECT * FROM [User]
LEFT OUTER JOIN [Profile] ON [Profile].[UserId] = [User].[UserId]
INNER JOIN [Department] ON [Department].[DepartmentId] = [Profile].[DepartmentId]

Users may or may not have a profile (but never more than one). A profile may or may not have a department (but never more than one).

Now, this will return only users that have a profile even though an outer join has been used. What I really want is to return all users and include their profile and department details but only when the profile has a department.

The solution I have used in the past is:

SELECT * FROM [User]
LEFT OUTER JOIN
(
SELECT *
FROM [Profile]
INNER JOIN [Department] ON [Department].[DepartmentId] = [Profile].[DepartmentId]
) [ProfileDepartment] ON [ProfileDepartment].[UserId] = [User].[UserId]

The trouble here is that I've lost the ability to reference department and profile independantly in the outer query. Also, more complex scenarios can also become horribly complex if this needs to be done multiple times in the same query.

I could do this:

SELECT * FROM [User]
LEFT OUTER JOIN [Profile] ON [Profile].[UserId] = [User].[UserId] AND [Profile].[DepartmentId] IS NOT NULL
LEFT OUTER JOIN [Department] ON [Department].[DepartmentId] = [Profile].[DepartmentId]

But again I feel that the intention is not at all clear. I want to inner join department to profile because I'm only interested in profiles with a department and departments referenced by a profile.

I would like to be able to specify that the departments should be inner joined to profiles and whichever profiles remain get outer joined to users whilst retaining department and profile as seperate entities within the query.

Is there any way to use brackets to indicate an order of precedance to the logical joins within the from clause?

Daniel

I think that this is pretty much the answer, though there is an easier way to write it

SELECT * FROM [User]
LEFT OUTER JOIN
(
SELECT *
FROM [Profile]
INNER JOIN [Department] ON [Department].[DepartmentId] = [Profile].[DepartmentId]
) [ProfileDepartment] ON [ProfileDepartment].[UserId] = [User].[UserId]

You can nest the joins to get the effect you want:

SELECT *
FROM [User]
LEFT OUTER JOIN [Profile]
INNER JOIN [Department] --this limits the department to the context of a Profile only!
ON [Department].[DepartmentId] = [Profile].[DepartmentId]
ON [Profile].[UserId] = [User].[UserId]

However, you have the same limitation that you could not in another join reference Department. You could nest in other tables to to get to the right combination, perhaps (it can get really messy fast if you have lots of tables to join :) So if you actually need to refer to the department in that context in a later join, then the two left outer joins might be the correct thing to do

SELECT *
FROM [User]
LEFT OUTER JOIN [Profile]
ON [Profile].[UserId] = [User].[UserId]
AND [Profile].[DepartmentId] IS NOT NULL
LEFT OUTER JOIN [Department]
ON [Department].[DepartmentId] = [Profile].[DepartmentId]

I don't see a problem with that syntax at all. You are correct that it is not as clear what your intention is, but, if you are joining department to multiple tables, that might be the case.

I highlighted in that context because if you need department in another context, it is valid to reference it again, as some alias:

SELECT *
FROM [User]
LEFT OUTER JOIN [Profile]
INNER JOIN [Department] --this limits the department to the context of a Profile only!
ON [Department].[DepartmentId] = [Profile].[DepartmentId]
ON [Profile].[UserId] = [User].[UserId]
INNER JOIN Department as otherDepartment
ON User.department = otherDepartment.DepartmentId

Or whatever. It is all in how you need to use the data.

|||

Hi Louis,

Thanks for the info; the nesting of joins is new syntax to me... Looks like I'm going to have to revisit my T-SQL code structure standards now!

I've tried the nexted join approach for the specific scenario I'm working on and it seems to work perfectly and also reads more clearly to me than the other two options.

I've also tried to extend it more than I need right now and it looks like you can reference the nested joined table in a different context, e.g.:

SELECT *

FROM [User]

LEFT OUTER JOIN [Profile]

INNER JOIN [Department] ON [Department].[DepartmentId] = [Profile].[DepartmentId]

ON [Profile].[UserId] = [User].[UserId]

LEFT OUTER JOIN [BusinessUnit] ON [BusinessUnit].[BusinessUnitId] = [Department].[BusinessUnitId]

AND [BusinessUnit].[BusinessUnitId] = [User].[BusinessUnitId]

I think you were saying that the above example would not work because the department table is only visible inside the scope of the "profile" join but the above example does work OK. Have I misunderstood what you were saying or could this be a change in SQL 2005?

Daniel

Friday, March 9, 2012

Missing SSAS Diagrams

I've created multiple SSAS diagrams and saved them back to the server. The next day, I connected to the server and the diagrams are gone. Rather than recreate all of them, I recreated one and tried saving it back to the server. I get the message stating "updating server", but when I close out and get back in the diagram is missing again. We have so many cubes we really need these so everyone can have a visualization of the structure. I even tried saving the project and reprocessing the database to no avail. Please help.

Many Thanks.

Scott,

When you say diagrams, are you referring to diagrams within the DSV for an SSAS project? Or something else?

Dave Fackler

|||

Hi Dave,

Thanks for your reply. I've figured it out. The diagrams were just on the server. I had to create a new project and download a more recent copy of the SSAS database. Feeling really smart:)

Thanks again,

Scott

Wednesday, March 7, 2012

Missing ODBC Driver

I have a Windows 2000 development server with multiple instance of SQL Server 2000 Dev Edition installed. Recently, i encounter an error on Enterpise Manager.

"A connection could not be established to SERVERNAME\INSTANCENAME.
Reason : Data source name not found and no default driver specified.
Please verify SQL Server is running and check your SQL Server registration properties(by right-clicking on the SERVERNAME\INSTANCENAME node) and try again."

I tried to use Query Analyser on the server to connect to instance. And receive this error

"Unable to connect to server SERVERNAME\INSTANCENAME:
ODBC: Msg 0, Level 16, State 1
[Microsoft][ODBC Driver Manager]Data source name not found and no default driver specified"

I tried connecting using IPAddr\InstanceName and it return the same error.
But if I use another machine (not the Development Server), I can connect to the instance sucessfully using Query Analyser.
Opening up the ODBC Data Source Adminsitrator, under the Drivers tab page, it is empty. So I tried re-installing MDAC 2.8 and also SP1, the installation completed sucessfully but the drivers is still missing. Tried searching on the MSDN site, shows, ODBC Driver cannot be un-installed.
Anybody can help on this ?
Have you changed anyhting on your PC recently? Any updates to the Windows or server? Have you tried to run Component Checker that comes with MDAC to see what could be corrupted in MDAC installation?|||Component Checker reported that I have MDAC 2.8 SP1 ON WINDOWS XP SP2.
But my OS is Windows 2000 SP4|||Does it show any error for the installed drivers/providers?|||I ran the check against the SP and it shows 3 files with mismatch

File : odbcjt32.dll
Mixmatch Fields : Expected : version = 4.0.6304.0
Path : C:\WINNT\system32\
Version : 4.0.6200.0
FileVersion : 4.06200.0
FileDescription : Microsoft ODBC Desktop Driver Pack 3.5
CodePage : 1252
Size : 270608
Date : 06/19/2003

File : msxml3.dll
Mixmatch Fields : Expected : version = 8.50.2162.0
Path : C:\WINNT\system32\
Version : 8.70.1104.0
FileVersion : 8.70.1104.0
FileDescription : MSXML 3.0 SP7
CodePage : 1200
Size : 1049088
Date : 02/18/2005

File : odbcji32.dll
Mixmatch Fields : Expected : version = 4.0.6304.0
Path : C:\WINNT\system32\
Version : 4.0.6200.0
FileVersion : 4.06200.0
FileDescription : Microsoft ODBC Desktop Driver Pack 3.5
CodePage : 1252
Size : 53520
Date : 07/22/2002|||I ran the check against "MDAC 2.8 SP1 ON WINDOWS XP SP2."|||Is the problem i am facing related to SQL Server Data Access or should i post this in Windows 2000 forum instead ?|||It is more related to the Windows installation rather than Data Access to SQL Server. In my opinion MDAC is corrupted somehow|||Thanks for replying.