如果两列中的数据集匹配> = 4次,如何选择*

Coo*_*and 2 sql-server sql-server-2012

我正在尝试提取有关重复调度的信息,但似乎无法提出一个简单的解决方案来提取我的报告数据。

我有下表:

tblMaster15

 ID | Equipment
----------------
  1 |   Sink
----------------
  2 |   Grill
Run Code Online (Sandbox Code Playgroud)

另一个包含位置信息的表,我必须使用 ID 加入:

tblMaster15_ABData

 ID | Unit | Region
--------------------
  1 | 600  |  6000
--------------------
  2 | 601  |  7000
Run Code Online (Sandbox Code Playgroud)

我正在尝试生成 ID、单位和设备的列表,但前提是单位和设备在给定时间段内相同超过 3 次。

我已经尝试了以下但它似乎给了我一切,而不仅仅是计数 > 3 的地方。

select   m.mrid, a.unit, a.Region, m.Equipment
from     MASTER36 m
join     MASTER36_ABDATA a
on       m.mrid = a.mrid
, (select   a.unit, m.Equipment
   from     MASTER36 m
   join     MASTER36_ABDATA a
   on       m.mrid = a.mrid
   group by a.unit, m.Equipment 
   having   count(*) > 3
  ) T2
where    a.unit = t2.unit
and      m.Equipment = t2.Equipment 
and      mrSUBMITDATE between '2/7/17' and '3/7/17'
and      mrstatus <> 'DELETED'
and      mrstatus <> 'Canceled'
and      m.Equipment  <> 'BLDNG
Run Code Online (Sandbox Code Playgroud)

我认为您不需要状态或提交日期。状态为关闭或打开。以这种格式提交日期:2017-01-01 00:50:24.000

我正在使用 SQL Server 2012。

And*_*y M 5

您正在计算整个数据集中的 Unit 和 Equipment 的出现次数,而不是具体在某个时间段内,其中某些组合很可能出现 3 次以上,而其他组合则很少出现或从未出现过。

因此,您需要对派生表应用相同的日期范围过滤器,以使结果反映您的要求:

select   m.mrid, a.unit, a.Region, m.Equipment
from     MASTER36 m
join     MASTER36_ABDATA a
on       m.mrid = a.mrid
join     (select   a.unit, m.Equipment
           from     MASTER36 m
           join     MASTER36_ABDATA a
           on       m.mrid = a.mrid
           where    mrSUBMITDATE between '2/7/17' and '3/7/17'
           group by a.unit, m.Equipment 
           having   count(*) > 3
         ) t2
on       a.unit = t2.unit
and      m.Equipment = t2.Equipment 
where    mrSUBMITDATE between '2/7/17' and '3/7/17'
and      mrstatus <> 'DELETED'   -- these two can be inlined:
and      mrstatus <> 'Canceled'  -- mrstatus not in ('DELETED', 'Canceled')
and      m.Equipment  <> 'BLDNG';
Run Code Online (Sandbox Code Playgroud)

注意:如您所见,为了保持一致性,我还重写了与派生表的连接以使用显式连接语法。

您也可以尝试这个替代方案,它只引用每个表一次并且不重复逻辑的任何部分:

select   mrid, unit, Region, Equipment
from     (
           select   m.mrid, a.unit, a.Region, m.Equipment, mrStatus,
                    cnt = count(*) over (partition by a.unit, m.Equipment)
           from     MASTER36 m
           join     MASTER36_ABDATA a
           where    mrSUBMITDATE between '2/7/17' and '3/7/17'
           and      m.Equipment  <> 'BLDNG'
         ) as derived
where    cnt > 3
and      mrstatus not in ('DELETED', 'Canceled');
Run Code Online (Sandbox Code Playgroud)

查询使用窗口聚合函数,而不是使用普通聚合函数计算行数。窗口聚合函数允许您返回聚合结果和非聚合数据。

在上面的查询中,您可以看到部分逻辑直接应用于连接的表,在行计数的范围内。其他过滤器在外层应用到派生表,以免影响 的结果count(*),从而匹配原始查询的逻辑。

过滤器count(*)也应用于派生表之外,因为计算列不能在定义它们的同一范围内过滤,特别是窗口函数不能在 WHERE 子句中使用。

最后,请考虑以下几点,以确保查询的可维护性和清晰度: