【问题标题】:Determine which OR statement selected the record?确定哪个 OR 语句选择了记录?
【发布时间】:2011-01-17 23:24:08
【问题描述】:

我在criteria 表的记录中保存了条件,我用它来创建一个动态查询字符串,该字符串将查询source 表,该查询的结果将插入到destination 表中.如果条件与source 表中的记录匹配,我的目标是将criteria 表中的ID 插入destination 表中。如果匹配多个条件记录,我只需插入第一个。

WHERE 子句由多个部分OR'ing 构建而成,并且在每个部分中,条件是AND'ed 在一起。类似于以下内容:

insert into destinationTable(col1, col2, col3)
select col1, col2, col3
from sourceTable
where
--' begin generated code'
   (a = 525 and b = 324 and c = 4523) -- 'from criteria record 1'
or (d = 'asdf' and e = 3.43) -- 'from criteria record 2'
or (f = 234523 and g = 9823742) -- 'from criteria record 3'
etc...
--' end generated code'

我需要找到一种方法来确定哪个是第一个匹配条件的 OR 部分,并在目标表中插入相应的条件 id 怎么做?

【问题讨论】:

    标签: sql sql-server sql-server-2005 sql-server-2008


    【解决方案1】:

    您可以在 Select 子句中包含一个 case 语句,该语句将输出第一个成功的 OR 子句:

    Select ...
        , Case
            When a = 525 And b = 324 And C = 4523 Then Criteria_Row_1_Pk
            When d = 'asdf' and e = 3.43 Then Criteria_Row_2_Pk
            ....
            End As SuccessClausePk
    

    【讨论】:

      【解决方案2】:

      将 or 替换为并集并添加一列给出标准编号

      select col1, col2, col3, 1
      from sourceTable
      where
      --' begin generated code'
         (a = 525 and b = 324 and c = 4523) -- 'from criteria record 1'
      union all
      select col1, col2, col3, 2
      from sourceTable
      where (d = 'asdf' and e = 3.43) -- 'from criteria record 2'
      union all
      select col1, col2, col3, 3
      from sourceTable
      where (f = 234523 and g = 9823742) -- 'from criteria record 3'
      etc...
      

      【讨论】:

      • 很好,但这不能在目标表中创建重复记录吗?
      • 子查询它并使用 Min(lastcolumn) 类似 select col1, col2, col3, min(which) from (select col1..., 1 as Which from ... union... ) subq按 col1、col2、col3 分组
      • 好吧,我也可以将 UNION ALL 更改为 UNION 以执行不同的查询,但我想知道这是否会像其他解决方案一样有效?
      • 重新重复 - OP 不清楚如果匹配 2 个条件会发生什么
      • 重新效率 - 取决于数据和指标,因此您必须尝试看看。
      【解决方案3】:

      除非可能有一个索引可以为所涉及的所有列提供服务,否则该表很可能会被完全扫描。由于我们要检查所有记录,您不妨进行过滤之前进行确定。

      SELECT col1, col2, col3, Which
      FROM
      (
          select col1, col2, col3,
          CASE
          --' begin generated code'
          WHEN 
             (a = 525 and b = 324 and c = 4523) -- 'from criteria record 1'
          THEN 1
          WHEN
             (d = 'asdf' and e = 3.43) -- 'from criteria record 2'
          THEN 2
          WHEN
             (f = 234523 and g = 9823742) -- 'from criteria record 3'
          THEN 3
          --' end generated code'
          END Which
          from sourceTable
      ) SQ
      WHERE Which is not null -- remove where it didn't match any criteria
      

      表单是可预测且一致的,足以对代码生成友好

      【讨论】:

      • 有趣,我以为我将不得不重复 CASE 语句和 WHERE 子句中的标准。我很想知道这是否表现良好。
      • @cyberwiki 我们确实在源表上有一个索引,并且查询将始终包含至少一个将使用该索引的条件。您认为这种方法仍然可行还是我们应该重复 WHERE 子句中的标准?
      • SQL Server 没有水晶球。性能总是因各种原因而变化,所以我会测试所有查询,看看哪个最合适。 “至少有一个条件将使用该索引”不足以阻止扫描,因为还有其他条件不能使用该索引,并且查询需要检查所有条件。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-24
      • 1970-01-01
      • 2017-04-12
      • 1970-01-01
      相关资源
      最近更新 更多