【问题标题】:SQL Server - identify successful where clauseSQL Server - 识别成功的where子句
【发布时间】:2014-07-27 19:49:24
【问题描述】:

我需要有关 T-SQL 的帮助。我的 SQL Server 中有一个存储过程,查询(示例)如下:

select mpid, empname, sal, phone, [e-mail]
from emp
where empid = @empid or empname = @empname or sal = @sal or phone = @phone

在上面的示例查询中,我的 where 子句中有四个条件。当我运行查询时,如果任何条件与输入变量匹配(例如:@empid、@empname 等),我都会得到结果。

我现在的要求是确定哪些条件与输入数据匹配。我只需要知道与输入值匹配的 first where 条件。

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    您可以在SELECT 中使用CASE 语句来做到这一点:

    Select  empid, 
            empname, 
            sal,
            phone,
            [e-mail],
            Case 
                When empid = @empid     Then 'EmpId'
                When empname = @empname Then 'EmpName'
                When sal = @sal         Then 'Sal'
                When phone = @phone     Then 'Phone'
            End As MatchingColumn
    From    emp
    Where   empid = @empid 
        Or      empname = @empname  
        Or      sal = @sal 
        Or      phone = @phone
    

    【讨论】:

    • 对不起,我忘了一点。我有大约 40 个这样的专栏。所以,我不想写“案例”陈述:-(
    • 您有 40 个Or 条件?我认为最简单的方法是为每个条件设置一个Case。我不知道找到哪个Or 语句首先匹配的更简单的替代方法。
    • @Prawin 很抱歉,但这应该是你能做到这一点的唯一方法。此外,除了调试目的之外,您为什么需要知道众多条件中的哪一个评估为真?
    • 基本上,我需要向最终用户显示一条关于数据匹配列的消息! (例如“记录与您的员工姓名匹配”或“记录与您的薪水匹配”等。)
    • 解决方案无法确定,哪个确切条件形成了结果行。我的意思是,如果几个 2 搜索字段相等怎么办?
    【解决方案2】:

    修改后的戈登林诺夫答案

    Select  empId,EName,Sal,Phone,Match From
    (select empId,EName,Sal,Phone,
        ((case when empId=@empId Then (CONVERT(VARCHAR,empId) +';'+ 'empId')
               when EName=@EName Then (CONVERT(VARCHAR,EName) +';'+ 'EName')
               when Sal=@Sal Then (CONVERT(VARCHAR,Sal) +';'+ 'Sal')
               when Phone=@Phone Then (CONVERT(VARCHAR,Phone) +';'+ 'Phone')
               else NULL end)) as Match
          from Employee e
         ) e
    Where Match IS NOT NULL
    

    删除了每列的 case 语句,因为它将检查每列的条件,而不考虑满足条件

    因为the control will return as soon as any one of the conditions 成功,所以只为所有列添加了一个案例。

    【讨论】:

      【解决方案3】:

      我会将条件移动到子查询中。这样,您就不必在外部查询中重复它们:

      Select  empid, empname, sal, phone, [e-mail],
              Matches
      From (select e.*, 
                   ((case when empid = @empid Then 'EmpId;' else '' end) +
                    (case when empname = @empname Then 'EmpName;' else '' end) +
                    (case when sal = @sal Then 'sal;' else '' end) +
                    (case when phone = @phone Then 'phone;' else '' end) +
                    . . .
                   ) as Matches
            from emp e
           ) e
      Where Matches <> '';
      

      请注意,此方法返回所有匹配的列。

      【讨论】:

        【解决方案4】:

        实际上CASE 方法几乎不能满足您的要求。可能最可靠的确定方法是UNION ALL

        select empid, empname, sal, phone, [e-mail], MatchCol from
        (
        select empid, empname, sal, phone, [e-mail], 'empID' as MatchCol
        from emp where empid = @empid 
        union all
        select mpid, empname, sal, phone, [e-mail], 'empname' as MatchCol
        from empname = @empname 
        ...
        )
        

        然后过滤掉不同的重复例如

        【讨论】:

        • 这听起来像是相当多的开销。它必须对每一列执行相同的查询。
        • 没错——这里的性能开销很大,但结果与问题要求完全相关。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-13
        • 2015-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-09
        • 2021-08-09
        相关资源
        最近更新 更多