按优先级顺序检查多个表中的相同谓词

时间:2015-12-29 19:54:18

标签: sql-server-2008 tsql

我需要一个可以接受日期参数和employeeid的查询。那是容易的部分,对吧?!好吧,我有困难的部分是,然后我需要检查并查看table1中是否存在该日期和员工ID,如果它继续,如果不是,则检查table2。如果它存在于table2中,则继续,如果不存在,则检查table3。这个组合将在3个表中的一个表中,但我不确定在语法上设置它的最佳方法是什么?

编辑
一旦发现其中一个表中存在日期,所有处理都应该结束。它不应该继续下一个If Exists声明。因此,如果在第一个If Exists语句中找到日期,则所有处理都应该结束。

Declare @date datetime, @employeeid varchar(10)
Set @date = '01/01/2012'
Set @employeeid = 'vnm432'
IF EXISTS(Select Top 1 *
      FROM firsttable
      WHERE employeeid = @employeeid
      AND CAST(date As Date) = @date)
Begin
    'Continue processing here
End
IF EXISTS(Select Top 1 *
          FROM secondtable
          WHERE employeeid = @employeeid
          AND CAST(date As Date) = @date)
Begin
    'Continue processing here
End
IF EXISTS(Select Top 1 *
          FROM thirdtable
          WHERE employeeid = @employeeid
          AND CAST(date As Date) = @date)
Begin
    'Continue processing here
End

3 个答案:

答案 0 :(得分:2)

这种方法合理干燥,可以短路执行。

DECLARE @Flag INT;

WITH CTE1
     AS (SELECT 1 AS Priority, employeeid, date
         FROM   T1
         UNION ALL
         SELECT 2 AS Priority, employeeid, date
         FROM   T2
         UNION ALL
         SELECT 3 AS Priority, employeeid, date
         FROM   T3),
     CTE2
     AS (SELECT *
         FROM   CTE1
         WHERE  employeeid = @employeeid
                AND date >= @date
                AND date < DATEADD(DAY, 1, @date))
SELECT @Flag =
        CASE WHEN EXISTS (SELECT * FROM CTE2 WHERE Priority = 1) THEN 1
             WHEN EXISTS (SELECT * FROM CTE2 WHERE Priority = 2) THEN 2
             WHEN EXISTS (SELECT * FROM CTE2 WHERE Priority = 3) THEN 3
        END

enter image description here

它还使用more efficient predicate on date(如果employeeid, date已编入索引)而不是问题中的查询。

答案 1 :(得分:1)

从我的头脑中,我认为通过子查询和工会,你可以实现这一目标:

declare @foundIn varchar(15)
select @foundIn = foundIn  from 
(
select  top 1 foundIn from
(
 Select 'firsttable' as foundIn 
      FROM firsttable
      WHERE employeeid = @employeeid
      AND CAST(date As Date) = @date
UNION
 Select 'secondtable' as foundIn 
      FROM secondtable
      WHERE employeeid = @employeeid
      AND CAST(date As Date) = @date
UNION
 Select 'thirdtable' as foundIn 
      FROM thirdtable
      WHERE employeeid = @employeeid
      AND CAST(date As Date) = @date
) as q
) as q1

If @foundIn = 'firsttable'
    Begin
       'Continue processing here'       
    End
Else If @foundIn = 'secondtable'
    Begin
        'Continue processing here'
    End
Else If @foundIn = 'thirdtable'    
    Begin
        'Continue processing here'
    END

更新:

根据第一场比赛停止处理的新要求:

IF EXISTS(Select Top 1 *
      FROM firsttable
      WHERE employeeid = @employeeid
      AND CAST(date As Date) = @date)
Begin
    --Continue processing here
End
ELSE IF EXISTS(Select Top 1 *
      FROM secondtable
      WHERE employeeid = @employeeid
      AND CAST(date As Date) = @date)
BEGIN
    --Continue processing here
END
ELSE IF EXISTS(Select Top 1 *
      FROM thirdtable
      WHERE employeeid = @employeeid
      AND CAST(date As Date) = @date)
BEGIN
    --Continue processing here
END

答案 2 :(得分:1)

以下代码是对OP评论的回应。请注意,它不会在where子句中使用SARGABLE日期比较,这是史密斯博士回答的好处之一。

-- Sample data.
declare @Employees as Table ( EmployeeId VarChar(10), HireDate DateTime, ShoeSize VarChar(6) );
insert into @Employees ( EmployeeId, HireDate, ShoeSize ) values
  ( 'vnm123', '2012-01-01T12:00:00', '9' ), ( 'vnm432', '2012-01-01T12:00:00', '12W' ), ( 'xyzzy', '2012-01-01T12:00:00', '6N' );
select * from @Employees;
declare @Victims as Table ( EmployeeId VarChar(10), HireDate DateTime, ShoeSize VarChar(6) );
insert into @Victims ( EmployeeId, HireDate, ShoeSize ) values
  ( 'vnm123', '2012-01-01T12:00:00', '9' ), ( 'vnm431', '2012-01-01T12:00:00', '12W' ), ( 'xyzzy', '2012-01-01T12:00:00', '6N' );
select * from @Victims;

-- Do something.
declare @TargetDate as Date, @TargetEmployeeId as VarChar(10), @ShoeSize as VarChar(6);
select @TargetDate = '20120101', @TargetEmployeeId = 'vnm432';

select top 1 @ShoeSize = ShoeSize
  from @Employees
  where EmployeeId = @TargetEmployeeId and Cast( HireDate as Date ) = @TargetDate;
if @@RowCount = 1
  begin
  -- Process and return.
  select 'Employees' as [Table], @ShoeSize as ShowSize;
  return
  end

select top 1 @ShoeSize = ShoeSize
  from @Victims
  where EmployeeId = @TargetEmployeeId and Cast( HireDate as Date ) = @TargetDate;
if @@RowCount = 1
  begin
  -- Process and return.
  select 'Victims' as [Table], @ShoeSize as ShowSize;
  return
  end