在逗号分隔列表中查找管理器

时间:2013-08-08 21:03:17

标签: sql sql-server-2008 split comma

我有一个带有ID和Responsible manager的Projects表。对于项目1,负责任经理列的值为John,Jim,对于项目2,值为Jim,Julie

但如果我将Jim传递给我的存储过程,我应该得到2个项目(1,2)。这不返回任何行,因为该列为John,Jim,但SQL Server正在查找='Jim'

 select distinct ID,Manager from Projects where Manager=@Manager

4 个答案:

答案 0 :(得分:3)

WHERE ',' + Manager + ',' LIKE '%,Jim,%'

或者我想要匹配您的实际代码:

WHERE ',' + Manager + ',' LIKE '%,' + @Manager + ',%'

请注意,您的设计存在极大缺陷。没有理由你应该在这个表中存储名称,不要介意任何数据点的逗号分隔列表。这些事实本身就很重要,所以这样对待他们!

CREATE TABLE dbo.Managers
(
  ManagerID INT PRIMARY KEY,
  Name NVARCHAR(64) NOT NULL UNIQUE, ...
);

CREATE TABLE dbo.Projects
(
  ProjectID INT PRIMARY KEY,
  Name NVARCHAR(64) NOT NULL UNIQUE, ...
);

CREATE TABLE dbo.ProjectManagers
(
  ProjectID INT NOT NULL FOREIGN KEY REFERENCES dbo.Projects(ProjectID),
  ManagerID INT NOT NULL FOREIGN KEY REFERENCES dbo.Managers(ManagerID)
);

现在设置您提到的示例数据:

INSERT dbo.Managers(ManagerID, Name)
  VALUES(1,N'John'),(2,N'Jim'),(3,N'Julie');

INSERT dbo.Projects(ProjectID, Name)
  VALUES(1,N'Project 1'),(2,N'Project 2');

INSERT dbo.ProjectManagers(ProjectID,ManagerID)
  VALUES(1,1),(1,2),(2,2),(2,3);

现在找到Jim正在管理的所有项目:

DECLARE @Manager NVARCHAR(32) = N'Jim';

SELECT p.ProjectID, p.Name
  FROM dbo.Projects AS p
  INNER JOIN dbo.ProjectManagers AS pm
  ON p.ProjectID = pm.ProjectID
  INNER JOIN dbo.Managers AS m
  ON pm.ManagerID = m.ManagerID
  WHERE m.name = @Manager;

或者您甚至可以手动短路:

DECLARE @Manager NVARCHAR(32) = N'Jim';


DECLARE @ManagerID INT;
SELECT @ManagerID = ManagerID
  FROM dbo.Managers
  WHERE Name = @Manager;

SELECT p.ProjectID, p.Name
  FROM dbo.Projects AS p
  INNER JOIN dbo.ProjectManagers AS pm
  ON p.ProjectID = pm.ProjectID
  WHERE pm.ManagerID = @ManagerID;

甚至更多:

DECLARE @Manager NVARCHAR(32) = N'Jim';


DECLARE @ManagerID INT;
SELECT @ManagerID = ManagerID
  FROM dbo.Managers
  WHERE Name = @Manager;

SELECT ProjectID, Name
  FROM dbo.Projects AS p
  WHERE EXISTS 
  (
    SELECT 1 
      FROM dbo.ProjectManagers AS pm
      WHERE pm.ProjectID = p.ProjectID
      AND pm.ManagerID = @ManagerID
  );

顺便说一句,我真的非常希望原始查询中的DISTINCT是不必要的。您是否真的有多个具有相同名称​​和 ID的项目?

答案 1 :(得分:0)

WHERE子句中,=运算符会查找完全匹配。您可以使用带有通配符的LIKE进行部分匹配。

where Manager LIKE '%Jim%'

答案 2 :(得分:0)

您可以尝试以下方法:

SELECT DISTINCT 
    ID,
    Manager 
FROM 
    Projects 
WHERE 
    (
     (Manager LIKE @Manager + ',*') OR
     (Manager LIKE '*,' + @Manager) OR
     (Manager  = @Manager) 
    )

这应该涵盖名称和姓氏,同时仍然搜索文字值。然而,性能可能是一个问题,具体取决于表

答案 3 :(得分:0)

请尝试使用以下查询

select distinct ID,Manager from Projects where replace('#$#' + Manager + '#$#', ',', '#$#') like '%Jim%'