Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2008 在多个表中按优先级顺序检查同一谓词_Sql Server 2008_Tsql - Fatal编程技术网

Sql server 2008 在多个表中按优先级顺序检查同一谓词

Sql server 2008 在多个表中按优先级顺序检查同一谓词,sql-server-2008,tsql,Sql Server 2008,Tsql,我需要一个可以接受日期参数和employeeid的查询。这是最简单的部分,对吧?!我遇到的困难是,我需要检查表1中是否存在该日期和员工id,如果它继续存在,如果不存在,请检查表2。如果它存在于表2中,则继续,如果不存在,则检查表3。这个组合将在3个表中的一个表中,但我不确定从语法上设置它的最佳方式是什么 edit一旦发现其中一个表中存在日期,所有处理都应结束。它不应继续到下一个If Exists语句。因此,如果在第一个if Exists语句中找到日期,则所有处理都应结束 Declare @dat

我需要一个可以接受日期参数和employeeid的查询。这是最简单的部分,对吧?!我遇到的困难是,我需要检查表1中是否存在该日期和员工id,如果它继续存在,如果不存在,请检查表2。如果它存在于表2中,则继续,如果不存在,则检查表3。这个组合将在3个表中的一个表中,但我不确定从语法上设置它的最佳方式是什么

edit一旦发现其中一个表中存在日期,所有处理都应结束。它不应继续到下一个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

从我的想法来看,通过子查询和联合,您可以实现以下目标:

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

从我的想法来看,通过子查询和联合,您可以实现以下目标:

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

这种方法相当干燥,可能会导致执行短路

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

它还使用if employeeid,date比问题中的查询更容易索引。

这种方法相当枯燥,可能会缩短执行时间

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

它还使用了if employeeid,日期索引比问题中的查询要多。

下面的代码是对OP评论的响应。请注意,它在where子句中没有使用日期比较,这是史密斯博士答案的优点之一

-- 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

下面的代码是对OP评论的回应。请注意,它在where子句中没有使用日期比较,这是史密斯博士回答的优点之一

-- 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


如果需要,只需在变量和进程中选择行值,并在@RowCount为1时返回即可。或者这不是一个存储过程?@HABO-是的,它是一个存储过程。如何选择行值?我添加了一个包含示例代码的答案。如果需要,只需在变量中选择行值,然后在@RowCount为1时处理并返回。或者这不是一个存储过程?@HABO-是的,它是一个存储过程。我如何选择行值?我添加了一个包含示例代码的答案。如果有多个匹配项,则无法保证将分配给@foundIn的内容,这可能会不必要地访问表。@排名前1的MartinSmith保证只取第一个不,现在我看到了,没有订单,在阅读最新要求之前,我发布了,一旦发现其中一个表中存在日期,所有处理都应end@E-Bat那么,一旦找到相关的日期,这将停止处理,还是将迭代所有表?如果有多个匹配项,则无法保证将分配给@foundIn的内容,并且这可能会不必要地访问表。@排名前1的MartinSmith保证只需要第一个不,不是没有订单,现在我看到了,我在阅读更新的需求之前发布了,一旦发现其中一个表中存在日期,所有处理都应该end@E-Bat那么,一旦找到相关的日期,它会停止处理吗?或者它会迭代所有的表吗?你是什么意思?意思是关闭我的服务器?@RedLightGreenLight-可以在找到结果时避免访问其他表。什么意思可以使执行短路?意思是关闭我的服务器?@RedLightGreenLight-可以在找到结果时避免访问其他表。