I have the below 5 tables -
CREATE TABLE [dbo].[MSP_EpmProject](
[ProjectUID] [uniqueidentifier] NOT NULL,
[ProjectName] [nvarchar](255) NOT NULL,
[ProjectAuthorName] [nvarchar](255) NULL,
CONSTRAINT [PK_MSP_EpmProject] PRIMARY KEY CLUSTERED
([ProjectUID] ASC))
CREATE TABLE [dbo].[Project_CI_Mapping](
[ProjectName] [nvarchar](255) NOT NULL,
[CI] [nvarchar](100) NOT NULL)
CREATE TABLE [dbo].[ca_owned_resource](
[resource_name] [nvarchar](100) NOT NULL,
[resource_description] [nvarchar](255) NULL,
[resource_family] [int] NULL,
[resource_class] [int] NOT NULL,
[resource_status] [int] NULL,
[resource_tag] [nvarchar](64) NULL)
CREATE TABLE [dbo].[DimTeamProject](
[ProjectNodeSK] [int] IDENTITY(1,1) NOT NULL,
[ProjectNodeGUID] [uniqueidentifier] NOT NULL,
[ProjectNodeName] [nvarchar](256) NULL,
PRIMARY KEY CLUSTERED
([ProjectNodeSK] ASC))
CREATE TABLE [dbo].[DimIteration](
[IterationSK] [int] IDENTITY(1,1) NOT NULL,
[IterationName] [nvarchar](256) NULL,
[IterationGUID] [nvarchar](256) NOT NULL,
PRIMARY KEY CLUSTERED
([IterationSK] ASC))
I have a simple query that tries to get columns from all the tables, but it is returning me duplicate values. Trying INNER JOIN returns me duplicate values & when trying LEFT OUTER JOIN it gives me NULL values for "DimIteration.IterationName".
The query is -
select m.ProjectName,m.ProjectAuthorName "Project Manager", p.CI,c.resource_tag "Alt CI ID", i.IterationName
from MSP_EpmProject m, Project_CI_Mapping p, ca_owned_resource c, DimTeamProject t, DimIteration i
where i.ProjectGUID = UPPER(CAST(t.ProjectNodeGUID AS NVARCHAR(256)))
and p.CI = c.resource_name
and m.ProjectName = p.ProjectName
order by m.ProjectName,m.ProjectAuthorName, p.CI,c.resource_tag, i.IterationName
Possible Mappings are -
MSP_EpmProject.ProjectName = Project_CI_Mapping.ProjectName
Project_CI_Mapping.CI = ca_owned_resource.resource_name
ca_owned_resource.resource_tag = DimTeamProject.ProjectNodeName
DimIteration.ProjectGUID = UPPER(CAST(DimTeamProject.ProjectNodeGUID AS NVARCHAR(256)))
What would be a suitable solution for the same?
Thanks.
You have a CROSS JOIN in your query. If you rewrite it using the newer ANSI-92 syntax (which i would recommend doing anyway, for reasons explained here) you can see where the cross join lies:
select m.ProjectName,
m.ProjectAuthorName "Project Manager",
p.CI,c.resource_tag "Alt CI ID",
i.IterationName
from MSP_EpmProject m
INNER JOIN Project_CI_Mapping p
ON m.ProjectName = p.ProjectName
INNER JOIN ca_owned_resource c
ON p.CI = c.resource_name
CROSS JOIN DimTeamProject t
INNER JOIN DimIteration i
ON i.ProjectGUID = UPPER(CAST(t.ProjectNodeGUID AS NVARCHAR(256)))
order by m.ProjectName,m.ProjectAuthorName, p.CI,c.resource_tag, i.IterationName;
Basically there is nothing to relate DimTeamProject to any of the tables before hand. Based on the fact that you have this
ca_owned_resource.resource_tag = DimTeamProject.ProjectNodeName
as a possible relation, and it doesn't feature in your query at all I would suggest your query needs to be:
select m.ProjectName,m.ProjectAuthorName "Project Manager", p.CI,c.resource_tag "Alt CI ID", i.IterationName
from MSP_EpmProject m, Project_CI_Mapping p, ca_owned_resource c, DimTeamProject t, DimIteration i
where i.ProjectGUID = UPPER(CAST(t.ProjectNodeGUID AS NVARCHAR(256)))
and p.CI = c.resource_name
and m.ProjectName = p.ProjectName
and c.resource_tag = t.ProjectNodeName -- NEW Clause
order by m.ProjectName,m.ProjectAuthorName, p.CI,c.resource_tag, i.IterationName
However, as I've already said, I'd recommend ANSI 92 explicit joins so your query would become:
SELECT m.ProjectName,
m.ProjectAuthorName "Project Manager",
p.CI,c.resource_tag "Alt CI ID",
i.IterationName
FROM MSP_EpmProject m
INNER JOIN Project_CI_Mapping p
ON m.ProjectName = p.ProjectName
INNER JOIN ca_owned_resource c
ON p.CI = c.resource_name
INNER JOIN DimTeamProject t
ON t.ProjectNodeName = c.resource_tag
INNER JOIN DimIteration i
ON i.ProjectGUID = UPPER(CAST(t.ProjectNodeGUID AS NVARCHAR(256)))
ORDER BY m.ProjectName,m.ProjectAuthorName, p.CI,c.resource_tag, i.IterationName;
Without studying the question in too much detail, one way to get rid of duplicates is to insert a GROUP BY clause before the ORDER BY, like this:
select m.ProjectName,m.ProjectAuthorName "Project Manager", p.CI,c.resource_tag "Alt CI ID", i.IterationName
from MSP_EpmProject m, Project_CI_Mapping p, ca_owned_resource c, DimTeamProject t, DimIteration i
where i.ProjectGUID = UPPER(CAST(t.ProjectNodeGUID AS NVARCHAR(256)))
and p.CI = c.resource_name
and m.ProjectName = p.ProjectName
GROUP BY m.ProjectName,m.ProjectAuthorName, p.CI,c.resource_tag, i.IterationName
order by m.ProjectName,m.ProjectAuthorName, p.CI,c.resource_tag, i.IterationName
Another way is to insert DISTINCT after SELECT and before the first column you wish to return.
e.g. SELECT DISTINCT m.ProjectName...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With