Select 和内部联接返回重复项
Select and Inner Join Returning Duplicates
我正在开发一个查询来打印有关用户旅行的报告。但是,此查询 returning 4 行而不是两行。解释业务规则:用户创建旅行请求并添加不同的目的地作为路线。用户必须定义路线的每个子公司必须为旅行支付的百分比。行程可以有多个目的地,也可以只有一个。当我执行以下查询时:
Select Distinct sv.Description,
st.Description,
us.Code, us.Name,
rt.Destination, rt.Description, rt.BeginDate, rt.FInishDate,
rat.Percentage,
fl.Code, fl.Name
FROM TravelSolicitation sv
INNER JOIN Situation st ON sv.IdSituation = st.Id
INNER JOIN Duser us ON sv.IdUser = us.Id
INNER JOIN Itinerary rt ON rt.IdSolicitation = sv.Id
INNER JOIN Apportionment rat ON rat.IdSolicitation = sv.Id
INNER JOIN Subsidiary fl ON rat.IdSubsidiary = fl.Id
WHERE sv.Id = 1
我得到以下结果:
SQL Output
我的问题:
考虑到分配 table 查询结果应该只显示 2 行,因为每个子公司的分配是 80 和 20。如果我对 3 个子公司使用 3 种不同的分配(即 50、30、20),查询结果将显示 9线。我也尝试过使用 LEFT JOIN、RIGHT JOIN 和 OUTER JOIN,但它不起作用。
如何将此查询开发为 return 只有 2 行?
我的预期输出:
+----------+-------------+-----+------+------------+------+-----------+------------+------+---+------------+
| Travel 1 | Credit Test | 110 | Paul | Ny | Work | BeginDate | FinishDate | 20.0 | 4 | City B Sub |
+----------+-------------+-----+------+------------+------+-----------+------------+------+---+------------+
| Travel 1 | Credit Test | 110 | Paul | Washington | Fun | BeginDate | FinishDate | 80.0 | 2 | City A Sub |
+----------+-------------+-----+------+------------+------+-----------+------------+------+---+------------+
注意:我注意到分配 INNER JOIN 生成了 4 行。其他 INNER JOINS 显然有效。我正在使用 SQL 服务器
MVCE重现我的问题:
表格:
CREATE TABLE [Subsidiary] (
[Id] bigint NOT NULL,
[Code] varchar(4) NOT NULL,
[Name] varchar(40) NOT NULL,
CONSTRAINT [PK_Subsidiary_Id] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, DATA_COMPRESSION=NONE) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [Apportionment] (
[Id] bigint NOT NULL,
[IdSubsidiary] bigint NOT NULL,
[IdSolicitation] bigint NOT NULL,
[Percentage] decimal(19,4) NOT NULL,
CONSTRAINT [PK_Apportionment_Id] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, DATA_COMPRESSION=NONE) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [Itinerary] (
[Id] bigint NOT NULL,
[IdSolicitation] bigint NOT NULL,
[Destination] varchar(200) NULL,
[Description] varchar(50) NOT NULL,
[BeginDate] datetime NOT NULL,
[FInishDate] datetime NULL,
[MultipleItinerary] bit NOT NULL,
CONSTRAINT [PK_Itinerary_Id] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, DATA_COMPRESSION=NONE) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [Situation](
[Id] bigint NOT NULL,
[Name] varchar(40) NOT NULL,
[Description] varchar(150) NOT NULL,
[ValidateDate] smallint NOT NULL,
CONSTRAINT [PK_Situation_Id] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [TravelSolicitation]
([Id] bigint IDENTITY(1,1) NOT NULL,
[IdSituation] bigint NOT NULL,
[IdUser] bigint NOT NULL,
[Description] varchar(150) NOT NULL,
[GoDate] datetime NOT NULL,
[BackDate] datetime NOT NULL,
CONSTRAINT [PK_TravelSolicitation_Id] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, DATA_COMPRESSION=NONE) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [Duser] (
[Id] bigint NOT NULL,
[Code] varchar(10),
[Name] varchar(70) NOT NULL,
CONSTRAINT [PK_Duser_Id] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, DATA_COMPRESSION=NONE) ON [PRIMARY]
) ON [PRIMARY]
GO
外键:
ALTER TABLE Apportionment
ADD FOREIGN KEY (IdSubsidiary) REFERENCES Subsidiary(Id);
ALTER TABLE Apportionment
ADD FOREIGN KEY (IdSolicitation) REFERENCES TravelSolicitation(Id);
ALTER TABLE Itinerary
ADD FOREIGN KEY (IdSolicitation) REFERENCES TravelSolicitation(Id);
ALTER TABLE TravelSolicitation
ADD FOREIGN KEY (IdSituation) REFERENCES Situation(Id);
ALTER TABLE TravelSolicitation
ADD FOREIGN KEY (IdUser) REFERENCES Duser(Id);
插入
INSERT INTO Duser (Id,Code,Name) VALUES (1,110,'Paul')
INSERT INTO Situation (Id,Name,Description,ValidateDate) VALUES (1,'Situation A','Credit Test',1)
INSERT INTO Subsidiary (Id,Code,Name) VALUES (1,'2','City A Sub');
INSERT INTO Subsidiary (Id,Code,Name) VALUES (2,'4','City B Sub');
INSERT INTO TravelSolicitation(IdSituation,IdUser,Description,GoDate,BackDate) VALUES (1,1,'Travel 1','20-10-2021','20-11-2021');
INSERT INTO Itinerary (Id,IdSolicitation,Destination,Description,BeginDate,FInishDate,MultipleItinerary) VALUES (1,1,'Washington','Fun','20-10-2021','10-11-2021',1)
INSERT INTO Itinerary (Id,IdSolicitation,Destination,Description,BeginDate,FInishDate,MultipleItinerary) VALUES (2,1,'NY','Work','10-11-2021','20-11-2021',1)
INSERT INTO Apportionment(Id,IdSubsidiary,IdSolicitation,Percentage) VALUES (1,1,1,80.0)
INSERT INTO Apportionment(Id,IdSubsidiary,IdSolicitation,Percentage) VALUES (2,2,1,20.0)
只需在 INNER JOIN Apportionment rat ON rat.IdSolicitation = sv.Id
上添加 and rt.id = rat.id
。
由于您从未使用 rt.id
进行过滤,因此您的结果会返回 4 行。
Select Distinct sv.Description,
st.Description,
us.Code, us.Name,
rt.Destination, rt.Description, rt.BeginDate, rt.FInishDate,
rat.Percentage,
fl.Code, fl.Name
FROM TravelSolicitation sv
INNER JOIN Situation st ON sv.IdSituation = st.Id
INNER JOIN Duser us ON sv.IdUser=us.Id
INNER JOIN Itinerary rt ON rt.IdSolicitation = sv.Id
INNER JOIN Apportionment rat ON rat.IdSolicitation = sv.Id and rt.id = rat.id
INNER JOIN Subsidiary fl ON rat.IdSubsidiary=fl.Id
WHERE sv.Id = 1
我正在开发一个查询来打印有关用户旅行的报告。但是,此查询 returning 4 行而不是两行。解释业务规则:用户创建旅行请求并添加不同的目的地作为路线。用户必须定义路线的每个子公司必须为旅行支付的百分比。行程可以有多个目的地,也可以只有一个。当我执行以下查询时:
Select Distinct sv.Description,
st.Description,
us.Code, us.Name,
rt.Destination, rt.Description, rt.BeginDate, rt.FInishDate,
rat.Percentage,
fl.Code, fl.Name
FROM TravelSolicitation sv
INNER JOIN Situation st ON sv.IdSituation = st.Id
INNER JOIN Duser us ON sv.IdUser = us.Id
INNER JOIN Itinerary rt ON rt.IdSolicitation = sv.Id
INNER JOIN Apportionment rat ON rat.IdSolicitation = sv.Id
INNER JOIN Subsidiary fl ON rat.IdSubsidiary = fl.Id
WHERE sv.Id = 1
我得到以下结果:
SQL Output
我的问题: 考虑到分配 table 查询结果应该只显示 2 行,因为每个子公司的分配是 80 和 20。如果我对 3 个子公司使用 3 种不同的分配(即 50、30、20),查询结果将显示 9线。我也尝试过使用 LEFT JOIN、RIGHT JOIN 和 OUTER JOIN,但它不起作用。
如何将此查询开发为 return 只有 2 行?
我的预期输出:
+----------+-------------+-----+------+------------+------+-----------+------------+------+---+------------+
| Travel 1 | Credit Test | 110 | Paul | Ny | Work | BeginDate | FinishDate | 20.0 | 4 | City B Sub |
+----------+-------------+-----+------+------------+------+-----------+------------+------+---+------------+
| Travel 1 | Credit Test | 110 | Paul | Washington | Fun | BeginDate | FinishDate | 80.0 | 2 | City A Sub |
+----------+-------------+-----+------+------------+------+-----------+------------+------+---+------------+
注意:我注意到分配 INNER JOIN 生成了 4 行。其他 INNER JOINS 显然有效。我正在使用 SQL 服务器
MVCE重现我的问题:
表格:
CREATE TABLE [Subsidiary] (
[Id] bigint NOT NULL,
[Code] varchar(4) NOT NULL,
[Name] varchar(40) NOT NULL,
CONSTRAINT [PK_Subsidiary_Id] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, DATA_COMPRESSION=NONE) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [Apportionment] (
[Id] bigint NOT NULL,
[IdSubsidiary] bigint NOT NULL,
[IdSolicitation] bigint NOT NULL,
[Percentage] decimal(19,4) NOT NULL,
CONSTRAINT [PK_Apportionment_Id] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, DATA_COMPRESSION=NONE) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [Itinerary] (
[Id] bigint NOT NULL,
[IdSolicitation] bigint NOT NULL,
[Destination] varchar(200) NULL,
[Description] varchar(50) NOT NULL,
[BeginDate] datetime NOT NULL,
[FInishDate] datetime NULL,
[MultipleItinerary] bit NOT NULL,
CONSTRAINT [PK_Itinerary_Id] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, DATA_COMPRESSION=NONE) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [Situation](
[Id] bigint NOT NULL,
[Name] varchar(40) NOT NULL,
[Description] varchar(150) NOT NULL,
[ValidateDate] smallint NOT NULL,
CONSTRAINT [PK_Situation_Id] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [TravelSolicitation]
([Id] bigint IDENTITY(1,1) NOT NULL,
[IdSituation] bigint NOT NULL,
[IdUser] bigint NOT NULL,
[Description] varchar(150) NOT NULL,
[GoDate] datetime NOT NULL,
[BackDate] datetime NOT NULL,
CONSTRAINT [PK_TravelSolicitation_Id] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, DATA_COMPRESSION=NONE) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [Duser] (
[Id] bigint NOT NULL,
[Code] varchar(10),
[Name] varchar(70) NOT NULL,
CONSTRAINT [PK_Duser_Id] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, DATA_COMPRESSION=NONE) ON [PRIMARY]
) ON [PRIMARY]
GO
外键:
ALTER TABLE Apportionment
ADD FOREIGN KEY (IdSubsidiary) REFERENCES Subsidiary(Id);
ALTER TABLE Apportionment
ADD FOREIGN KEY (IdSolicitation) REFERENCES TravelSolicitation(Id);
ALTER TABLE Itinerary
ADD FOREIGN KEY (IdSolicitation) REFERENCES TravelSolicitation(Id);
ALTER TABLE TravelSolicitation
ADD FOREIGN KEY (IdSituation) REFERENCES Situation(Id);
ALTER TABLE TravelSolicitation
ADD FOREIGN KEY (IdUser) REFERENCES Duser(Id);
插入
INSERT INTO Duser (Id,Code,Name) VALUES (1,110,'Paul')
INSERT INTO Situation (Id,Name,Description,ValidateDate) VALUES (1,'Situation A','Credit Test',1)
INSERT INTO Subsidiary (Id,Code,Name) VALUES (1,'2','City A Sub');
INSERT INTO Subsidiary (Id,Code,Name) VALUES (2,'4','City B Sub');
INSERT INTO TravelSolicitation(IdSituation,IdUser,Description,GoDate,BackDate) VALUES (1,1,'Travel 1','20-10-2021','20-11-2021');
INSERT INTO Itinerary (Id,IdSolicitation,Destination,Description,BeginDate,FInishDate,MultipleItinerary) VALUES (1,1,'Washington','Fun','20-10-2021','10-11-2021',1)
INSERT INTO Itinerary (Id,IdSolicitation,Destination,Description,BeginDate,FInishDate,MultipleItinerary) VALUES (2,1,'NY','Work','10-11-2021','20-11-2021',1)
INSERT INTO Apportionment(Id,IdSubsidiary,IdSolicitation,Percentage) VALUES (1,1,1,80.0)
INSERT INTO Apportionment(Id,IdSubsidiary,IdSolicitation,Percentage) VALUES (2,2,1,20.0)
只需在 INNER JOIN Apportionment rat ON rat.IdSolicitation = sv.Id
上添加 and rt.id = rat.id
。
由于您从未使用 rt.id
进行过滤,因此您的结果会返回 4 行。
Select Distinct sv.Description,
st.Description,
us.Code, us.Name,
rt.Destination, rt.Description, rt.BeginDate, rt.FInishDate,
rat.Percentage,
fl.Code, fl.Name
FROM TravelSolicitation sv
INNER JOIN Situation st ON sv.IdSituation = st.Id
INNER JOIN Duser us ON sv.IdUser=us.Id
INNER JOIN Itinerary rt ON rt.IdSolicitation = sv.Id
INNER JOIN Apportionment rat ON rat.IdSolicitation = sv.Id and rt.id = rat.id
INNER JOIN Subsidiary fl ON rat.IdSubsidiary=fl.Id
WHERE sv.Id = 1