我创建了一个包含多个表的数据库。
与我的问题相关的表格:
个人资料表 http://imageshack.us/photo/my-images/838/profileqw.jpg/ 存储所有的porfiles
SalaryGroup表 http://imageshack.us/photo/my-images/255/salarygroup.jpg/ 存储所有工资
ProfileSalaryGroups http://imageshack.us/photo/my-images/138/profileandsalary.jpg/ 存储连接的配置文件和工资
我有几个插入配置文件/工资等的存储过程。我有一个连接配置文件和工资的过程,并将它们存储在“profileSalaryGroups”表中。 我还有一个程序可以获得与特定配置文件相关的所有工资。
这些程序执行以下操作:
连接个人资料&工资程序(完美地工作):
ALTER PROCEDURE [dbo].[ConnectProfileAndSalary]
-- Add the parameters for the stored procedure here
@ProfileName varchar(50) = '',
@Salaryname varchar(50) = ''
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
DECLARE @pId int
DECLARE @sId int
SELECT @pId = Id from [Profile] where Name = @ProfileName
SELECT @sId = Id from SalaryGroup where Name = @Salaryname
-- If the Id number already exists
IF ((SELECT COUNT(*) FROM ProfileSalaryGroups WHERE SalaryGroupId = @sId) > 0 OR
(SELECT COUNT(*) FROM ProfileSalaryGroups WHERE ProfileId = @pId) > 0)
RAISERROR ('Connection Exists', -- Message text.
16, -- Severity.
1 )
ELSE
INSERT INTO ProfileSalaryGroups (SalaryGroupId,ProfileId ) VALUES (@sId, @pId)
END
获取连接到特定配置文件的所有工资(完美地工作):
ALTER PROCEDURE [dbo].[GetConnectedSalaries]
-- Add the parameters for the stored procedure here
@ProfId int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT SalaryGroupId, s.Name from ProfileSalaryGroups ps
INNER JOIN SalaryGroup as s on s.Id = ps.SalaryGroupId
Where ps.ProfileId = @ProfId
END
问题:
我正在尝试创建一个程序,让我得到所有的非工资Id和名称 连接到个人资料。
我尝试了几种方法,例如:
SELECT SalaryGroupId, s.Name from ProfileSalaryGroups ps
INNER JOIN SalaryGroup as s on s.Id = ps.SalaryGroupId
Where ps.ProfileId != @ProfId
这让我得到了一半我想要的东西。我希望获得所有未连接到此配置文件的工资,但此代码返回所有工资ID和与配置文件连接的名称,但不返回我作为参数发送的工资,它不包括所有“SalaryGroup”表中存在的工资
SELECT s.Id, s.Name from SalaryGroup s
where NOT EXISTS (SELECT SalaryGroupId, s.Name, s.Id from ProfileSalaryGroups ps
INNER JOIN SalaryGroup as s on s.Id = ps.SalaryGroupId
Where ps.ProfileId = 17
)
这没有任何回报。
我已经有一段时间了,并尝试了其他一些方法(在某些情况下可笑)并且我被卡住了,如果需要更多信息,那么请问我将尽我所能提供它。
如果标题不正确那么我很抱歉,但我不知道该问题的标题是什么。如果@Admin有一个更好的标题,那么随时改变它。
谢谢!
答案 0 :(得分:0)
您可以使用左连接执行此操作,并查找连接右侧没有结果的位置:
SELECT
s.Id,
s.Name
from SalaryGroup s
left JOIN ProfileSalaryGroups as ps
on s.Id = ps.SalaryGroupId
Where ps.SalaryGroupId is null
这应该所有工资ID和名称,但删除SalaryGroup中匹配记录的位置(即s.profileId不为空)
答案 1 :(得分:0)
左外连接应该做你想要的:
select *
from SalaryGroup sal
left outer join ProfileSalaryGroups prof on
prof.Id = sal.Id
where prof.Id is null or prof.ProfileId != @ProfId
说明:prof.Id is null
选择那些没有配置文件的人,而prof.ProfileId != @ProfId
选择那些拥有个人资料但与当前配置文件不匹配的人。{/ p>
答案 2 :(得分:0)
从简单开始,解决问题。
首先,获取所有的salaryID
select *
from SalaryGroup s
left join ProfileSalaryGroup ps on ps.salaryGroupID=s.ID
现在,你不想要它们全部,所以要想办法消除它们中的一些。
要消除与参数匹配的组,请添加where子句
where ps.profileID <> @parameter
现在,如果您想在不匹配个人资料和以下
的情况下取消工资组and ps.ProfileID is NULL
左连接(而不是INNER JOIN)告诉SQL总是返回一行,无论第二个表中是否有匹配的数据。如果SQL找不到匹配项,则第二个表中的数据列都将为NULL。 WHERE子句的第一部分仅返回与参数不匹配的行。第二部分返回没有Profile Salary数据的行
答案 3 :(得分:0)
将参数作为LEFT JOIN的条件,并在WHERE子句
中检查ps.SalaryGroupId IS NULL
SELECT s.Id, s.Name
FROM SalaryGroup as s LEFT JOIN ProfileSalaryGroups ps on s.Id = ps.SalaryGroupId
AND ps.ProfileId = @ProfId
WHERE ps.SalaryGroupId IS NULL