【问题标题】:Selecting data based on 2 different criteria根据 2 个不同的标准选择数据
【发布时间】:2017-06-09 18:56:22
【问题描述】:

我有一张像这样的桌子......

ClientNo       ApptStrt        ApptEnd        Type
1774           1/27/2016       1/27/2016      A
1774           1/27/2016       1/27/2016      B
1174           2/2/2016        2/2/2016       B
186            1/12/2016       1/12/2016      A
186            1/11/2016       1/11/2016      B

此表包含数以万计的记录,类似于上面的数据。我的目标是找到所有同时具有 A 和 B 类型的客户记录,只有 A 和 B 的 ApptStrt 相同。

在这种情况下,客户端 1774 具有 A 和 B 类型 - 恰好两个 ApptStrt 日期相同,这与具有不同 ApptStrt 日期的 ClientNo 186 不同,即使具有两种类型。

期望的最终结果

ClientNo       ApptStrt        ApptEnd        Type
1774           1/27/2016       1/27/2016      A
1774           1/27/2016       1/27/2016      B

'这就是我一直在努力做的事情

Select x1.ClientNO, x1.ApptStrt, x1.ApptEnd, x1.Type from TblClientRecords X1
inner join tblClientRecords X2
On x1.appStrt = x2.appStrt
where x1.type in (A,B) 

不过,我正在尝试更具体 - 尤其是 TYPE,因为还有其他类型。所以最好能以某种方式确保它只寻找 A 和 B。我只寻找那些特定的。

【问题讨论】:

    标签: sql select sql-server-2012


    【解决方案1】:

    您可以group by client no 和 apptstrt 并检查这两种类型是否存在。

    select clientno,apptstrt
    from tblClientRecords
    group by clientno,apptstrt
    having count(case when type = 'A' then 1 end) >= 1
    and count(case when type = 'B' then 1 end) >= 1
    

    要获取整行,请将之前的结果连接到原始表中。

    select t.* 
    from tblClientRecords t
    join (
    select clientno,apptstrt
    from tblClientRecords
    group by clientno,apptstrt
    having count(case when type = 'A' then 1 end) >= 1
    and count(case when type = 'B' then 1 end) >= 1
    ) x on x.clientno=t.clientno and x.apptstrt=t.apptstrt
    

    【讨论】:

      【解决方案2】:

      上述方法可行,但似乎过于复杂。 如果将表连接到自身并限制 ON- 中的输出,则无需处理 GROUP_BY 子句即可获得此结果。 这也是一个一般情况,然后可以应用于很多情况。

      SELECT
          *
      FROM
          tblClientRecords  as A
      JOIN
          tblClientRecords  AS B
              ON 
              A.ClientNo = B.ClientNo
              AND A.ApptStrt = B.ApptStrt
              AND A.[Type] = A
              AND B.[Type] = B
      

      【讨论】:

      • 好的解决方案,只要他对 A 和 B 排成一排没问题。在想要的结果中,他有两个单独的行。
      • @mrek 我认为这没关系,因为行总是与 A 和 B 重复,如果有第三种类型,那么代码会变得更复杂,但可以遵循相同的逻辑。如果由于某种原因这是所需的格式,则使用 UNION ALL 创建重复行并在每个选择中添加 ,'A' 和 ,'B'
      【解决方案3】:

      您在 appStrt 上加入了两个别名,但还需要记住 clientno。然后,您还可以添加要求 x1 中的 type 不应等于 x2 中的 type 。由于您可以拥有比 AB 更多的类型,因此您需要为 x2 重复您的条件 x1.type in (A,B)嗯。

      我个人建议将这些条件与 exists 一起使用,而不是 join

      select x1.ClientNO, x1.ApptStrt, x1.ApptEnd, x1.Type from TblClientRecords X1
      where  x1.type in (A,B) and exists (select * from tblClientRecords X2
      where x1.ClientN = x2.ClientN and x1.appStrt = x2.appStrt and x1.type <> x2.type
      and x2.type in (A,B))
      

      【讨论】:

        猜你喜欢
        • 2014-05-22
        • 2021-04-07
        • 2018-09-25
        • 2014-04-10
        • 1970-01-01
        • 2013-07-04
        • 2017-12-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多