在where子句中使用逗号分隔值,并将其与in子句进行比较

时间:2011-06-18 07:56:04

标签: sql sql-server-2008

这是已编辑的完整问题。以下是表结构。 (下面只显示必要的列。)

表名:tblQualificationMaster

Qualiid  QualiName
-------  ---------
1        S.S.C  
2        H.S.C  
3        B.Sc  
4        M.C.A  
5        M.Sc(IT)  
6        B.E  
7        M.B.A  
8        B.Com  
9        M.E  
10       C.S  
12       M.Com

表名:tblAppResumeMaster

AppId  FirstName  LastName  TotalExpYears  TotalExpMonths  
-----  ---------  --------  -------------  --------------
1      Rahul      Patel     7              0  
2      Ritesh     Shah      0              0  
3      Ajay       shah      7              6  
4      Ram        Prasad    7              6  
5      Mohan      Varma     5              0  
6      Gaurav     Kumar     8              0  

表名:tblAppQualificationDetail。 (为了更好的阅读,我正在为除第一行之外的所有行编写逗号分隔值,但在我的数据库中,所有值都存储为appid=1,即每个qualificationid一行。)

Appid  QualiId  
-----  -------
1      1  
1      2  
1      3  
1      4  
2      1,2,3  
3      1,2,6  
4      1,2,3,5  
5      1,2,3,4  
6      1,2,6,9  

表名:tblVacancyMaster

VacId  Title           Criteria  Req.Exp  KeySkills
-----  --------------  --------  -------  ---------------
1      Programmer      4,5,6     4        .net,java,php
2      TL              4,5       3        .net,java,php
3      Project Mngr.   4,6,9     4        .net,java,php,sql
4      Java Developer  4,5,6     0        java,oracle,sql
5      Manager         7,9       7        bussiness management
6      Supervisior     3,8       3        marketing
7      PHP Developer   4,5       0        php,mysql,send

现在基于这个细节,我想创建应具有以下字段的视图。 (它显示为VacId=1,但我需要这个所有空缺,以便我可以触发此视图中的select * from view where VacId=3条款。)

AppId  FirstName  LastName  QualiName  QualiId  TotalExp  VacId  VacTitle
-----  ---------  --------  ---------  -------  --------  -----  ----------
1      Rahul      Patel     M.C.A      4        7         1      Programmer
3      Ajay       Shah      B.E.       6        7         1      Programmer
5      Mohan      Verma     M.C.A      4        5         1      Programmer
6      Gaurav     Kumar     B.E        6        8         1      Programmer
6      Gaurav     Kumar     M.E        9        8         1      Programmer

此视图显示AppId 1,3,5和6有资格获得空缺3,但它显示应用程序6的重复条目。如何获得唯一记录?

我在数据库设计方面可能有问题,因为这是我的第一个项目,我正在学习数据库,所以如果出现违反数据库标准的事情,请告诉我并纠正。

我以前的查询 (注意:之前我使用的是一个中间表tblVacancyCriteriaDetail,其中包含VacIdQualiId列,而我的表tblVacancyMaster没有列标准)

select
  ARM.AppId,
  ARM.AppFirstName,
  ARM.AppLastName,
  ARM.AppMobileNo,
  AQD.QualiId,
  VacQualiDetail.QualiName,
  ARM.AppEmailId1,
  VacQualiDetail.VacID,
  ARM.TotalExpYear,
  VacQualiDetail.VacTitle,
  VacQualiDetail.DeptId,
  VacQualiDetail.CompId,
  CM.CompName  
from
  tblAppResumeMaster ARM,
  tblAppQualificationDetail AQD,
  tblCompanyMaster CM,
  (
    select
      VM.VacID,
      VM.VacTitle,
      VM.CompId,
      VM.DeptId,
      vcd.QualificationID,
      QM.QualiName,
      VM.RequiredExperience as Expe
    from
      tblVacancyCriteriaDetail VCD,
      tblVacancyMaster VM,
      tblQualificationMaster QM
    where VCD.VacID=VM.VacID
      and VCD.QualificationID=QM.QualificationId
      and VM.Status=0
  ) as VacQualiDetail
where AQD.AppId=arm.AppId
  and aqd.QualiId=VacQualiDetail.QualificationID
  and ARM.TotalExpYear>=Expe
  and cm.CompId=VacQualiDetail.CompId

4 个答案:

答案 0 :(得分:3)

create view vAppList as
select AppId, 
       FirstName, 
       LastName, 
       QualiName, 
       Qualiid, 
       TotalExpYears, 
       VacId, 
       Title
from (select ARM.AppId,
             ARM.FirstName,
             ARM.LastName,
             QM.QualiName,
             QM.Qualiid,
             ARM.TotalExpYears,
             VM.VacId,
             VM.Title,
             row_number() over(partition by ARM.AppId, VM.VacId order by QM.Qualiid) as rn
      from tblAppResumeMaster as ARM
        inner join tblAppQualificationDetail as AQD
          on ARM.AppId = AQD.Appid
        inner join tblQualificationMaster as QM
          on AQD.QualiId = QM.Qualiid  
        inner join tblVacancyMaster as VM
          on  ','+VM.Criteria+',' like '%,'+cast(QM.Qualiid as varchar(10))+',%'    
     ) as V
where V.rn = 1

当一个申请人匹配多个资格时,子查询将有重复。在这种情况下,QualiName将具有最低Qualiid的值。

如果你回去使用我认为你应该使用的tblVacancyCriteriaDetail,那么视图将会是这样的。

create view vAppList as
select AppId, 
       FirstName, 
       LastName, 
       QualiName, 
       Qualiid, 
       TotalExpYears, 
       VacId, 
       Title
from (select ARM.AppId,
             ARM.FirstName,
             ARM.LastName,
             QM.QualiName,
             QM.Qualiid,
             ARM.TotalExpYears,
             VM.VacId,
             VM.Title,
             row_number() over(partition by ARM.AppId, VM.VacId order by QM.Qualiid) as rn
      from tblAppResumeMaster as ARM
        inner join tblAppQualificationDetail as AQD
          on ARM.AppId = AQD.Appid
        inner join tblQualificationMaster as QM
          on AQD.QualiId = QM.Qualiid
        inner join tblVacancyCriteriaDetail as VCD    
          on QM.Qualiid = VCD.QualiID
        inner join tblVacancyMaster as VM
          on  VCD.VacId = VM.VacId
     ) as V
where V.rn = 1     

答案 1 :(得分:1)

我从未使用过MS SQL Server,所以我认为最好的方法是使用Regex(尝试在SQL Server文档中找到它的内容)。

但我认为这应该有效:

select * from Table1 Where (',' + qualificationid + ',') like '%,6,%';

我假设字符串连接是使用+符号完成的。

答案 2 :(得分:0)

修订:

创建一个新功能:

CREATE FUNCTION Split(@String varchar(8000), @Delimiter char(1))     
returns @temptable TABLE (items varchar(8000))     
as     
begin     
    declare @idx int     
    declare @slice varchar(8000)     

    select @idx = 1     
        if len(@String)<1 or @String is null  return     

    while @idx!= 0     
    begin     
        set @idx = charindex(@Delimiter,@String)     
        if @idx!=0     
            set @slice = left(@String,@idx - 1)     
        else     
            set @slice = @String     

        if(len(@slice)>0)
            insert into @temptable(Items) values(@slice)     

        set @String = right(@String,len(@String) - @idx)     
        if len(@String) = 0 break     
    end 
return     
end

然后你可以使用我以前的答案:

SELECT * FROM TableA WHERE ColumnID IN split(SELECT ColumnWithValues FROM TableB)

答案 3 :(得分:0)

尝试使用COALESCE函数将您的行放在一列中,并使用逗号分隔。这是一个简单的检查

 declare @QualIDs varchar(50)=''
 select  @QualIDs= COALESCE(@QualIDs+ ', ', '') + CAST(Qualiid AS varchar(50)))
 from tblQualificationMaster

这将以逗号分隔返回所有Qualiid,您可以在where子句或子查询中使用它。

要详细了解COALESCE,请转到http://msdn.microsoft.com/en-us/library/ms190349.aspx