【问题标题】:Filter for max effective dating过滤最大有效约会
【发布时间】:2019-10-04 18:43:37
【问题描述】:

我有以下查询,它可以让我得到至少有两行 COVERAGE_ELECT = 'E' 并且计划类型为 49 的 EMPLID。

WITH Coverage_CTE (EMPLID, COVERAGE_ELECT)
 AS
  (
  SELECT EMPLID, COUNT(COVERAGE_ELECT) 
  FROM PS_SAVINGS_PLAN
  WHERE COVERAGE_ELECT = 'E'
  AND PLAN_TYPE = '49'
  GROUP BY EMPLID
  HAVING COUNT(COVERAGE_ELECT) > 1 
  )
, Emp_CTE (EMPLID)
AS
(
  select distinct EMPLID from Coverage_CTE
)
  SELECT SP.EMPLID, SP.PLAN_TYPE, SP.EFFDT, SP.COVERAGE_ELECT, SP.SAVINGS_COVRG, SP.FLAT_DED_AMT, SP.PCT_GROSS
  FROM PS_SAVINGS_PLAN as SP
  WHERE SP.EMPLID IN (Select EMPLID from Emp_CTE)
  AND SP.COVERAGE_ELECT = 'E'
  AND PLAN_TYPE = '49'

这似乎工作正常,但是我想进一步过滤结果,仅包含EMPLID 没有行且有效日期大于最大EFFDT 的行上面选择的 E' 行 是“W”或“T”。

上述查询当前有EMPLID 5423H 的行(因为您看到的这个人有超过1 行COVERAGE_ELECT = 'E' 行(3))。但是,您会看到此人有两行,COVERAGE_ELECT 等于 T 和 W,EFFDT 大于最大 EFFDT 'E' 行 (2018-10-01) 的生效日期。

EMPLID      PLAN_TYPE    EFFDT         COVERAGE_ELECT
5423H       49           2013-01-01    W
5423H       49           2015-10-02    E
5423H       49           2015-10-09    T
5423H       49           2016-09-29    E
5423H       49           2018-10-01    E
5423H       49           2018-10-07    T
5423H       49           2018-11-14    W

因此,您在此示例中看到了这两种情况 - 1. 此 EMPLID 的“T”行大于 (2018-10-07) 最大 EFFDT“E”行 (2018-10-01) 和2. 他们有一排 'W' 大于 (2018-11-14) 最大 EFFDT 'E' 行。如果其中任何一种情况为真,那么我不希望它们导致我上面的查询。我希望将此附加逻辑构建到上述查询中。我希望这是有道理的..

【问题讨论】:

  • 。 .你的问题真的很复杂,很难理解。更是如此,因为您的原始查询不是实现逻辑的好方法。我可能会建议您从一个新问题开始,询问如何重新实现您的查询。
  • Emp_CTE 似乎毫无意义。 Coverage_CTE 按 EMPLID 分组,所以我认为 DISTINCT 是多余的。

标签: sql sql-server-2014


【解决方案1】:

根据您的叙述,这可以基于简单的条件聚合来回答:

WITH Coverage_CTE AS
 (
   SELECT EMPLID 
     ,Count(CASE WHEN COVERAGE_ELECT IN ('E') THEN effdt end) AS cntE
     ,Max(CASE WHEN COVERAGE_ELECT IN ('T', 'W') THEN effdt end) AS maxT
     ,Max(CASE WHEN COVERAGE_ELECT IN ('E') THEN effdt end) AS maxE

   FROM @PS_SAVINGS_PLAN
   WHERE PLAN_TYPE = '49'
   GROUP BY EMPLID
 )
SELECT EMPLID FROM Coverage_CTE
WHERE 
   -- at least two rows with COVERAGE_ELECT = 'E'       
   cntE > 1

   -- where there isn't a row for the EMPLID with an effective date that is greater
   -- than the max EFFDT of the 'E' rows selected above that is either a 'W' or a 'T'
  AND (maxT < maxE OR maxT IS NULL)

【讨论】:

  • 您的查询比提供的其他答案少了大约 100 行。有什么想法吗?
  • 也许AND (maxT &lt;= maxE OR maxT IS NULL)
【解决方案2】:

所有未测试 我会更改您的 CTE 以包含最大 effdt,为最大 WT EFFDATE 添加另一个 CTE,然后选择您最喜欢的方法来排除另一个。

LEFT JOIN 和 WHERE 为空:

;WITH Coverage_CTE (EMPLID, COVERAGE_ELECT, MAXEFFDT)
AS (
    SELECT EMPLID, COUNT(COVERAGE_ELECT), MAX(EFFDT) MAXEFFDT
    FROM PS_SAVINGS_PLAN
    WHERE COVERAGE_ELECT = 'E'
       AND PLAN_TYPE = '49'
    GROUP BY EMPLID
    HAVING COUNT(COVERAGE_ELECT) > 1 
)
, WT_Coverage_CTE (EMPLID, WTMAXEFFDT)
As (
   SELECT EMPLID, MAX(EFFDT) WTMAXEFFDT
   FROM PS_SAVINGS_PLAN
    WHERE COVERAGE_ELECT IN ('W', 'T')
       AND PLAN_TYPE = '49'
    GROUP BY EMPLID
)

SELECT SP.EMPLID, SP.PLAN_TYPE, SP.EFFDT, SP.COVERAGE_ELECT, 
SP.SAVINGS_COVRG, 
       SP.FLAT_DED_AMT, SP.PCT_GROSS
    FROM PS_SAVINGS_PLAN as SP
INNER JOIN Coverage_CTE CCTE on CCTE.EMPLID = SP.EMPLID
LEFT OUTER JOIN WT_Coverage_CTE WTCTE
   on WTCTE.EMPLID = CCTE.EMPLID
   and WTCTE.WTMAXEFFDT > CCTE.MAXEFFDT
WHERE SP.COVERAGE_ELECT = 'E'
   AND PLAN_TYPE = '49'
   AND WTCTE.EMPLID is null

不存在:

;WITH Coverage_CTE (EMPLID, COVERAGE_ELECT, MAXEFFDT)
AS (
    SELECT EMPLID, COUNT(COVERAGE_ELECT), MAX(EFFDT) MAXEFFDT
    FROM PS_SAVINGS_PLAN
    WHERE COVERAGE_ELECT = 'E'
       AND PLAN_TYPE = '49'
    GROUP BY EMPLID
    HAVING COUNT(COVERAGE_ELECT) > 1 
)
, WT_Coverage_CTE (EMPLID, WTMAXEFFDT)
As (
   SELECT EMPLID, MAX(EFFDT) WTMAXEFFDT
   FROM PS_SAVINGS_PLAN
    WHERE COVERAGE_ELECT IN ('W', 'T')
       AND PLAN_TYPE = '49'
    GROUP BY EMPLID
)

SELECT SP.EMPLID, SP.PLAN_TYPE, SP.EFFDT, SP.COVERAGE_ELECT, SP.SAVINGS_COVRG, 
   SP.FLAT_DED_AMT, SP.PCT_GROSS
FROM PS_SAVINGS_PLAN as SP
INNER JOIN Coverage_CTE CCTE on CCTE.EMPLID = SP.EMPLID
WHERE SP.COVERAGE_ELECT = 'E'
   AND PLAN_TYPE = '49'
   AND NOT EXISTS (SELECT EMPLID
                   FROM WT_Coverage_CTE WTCTE
                   WHERE WTCTE.EMPLID = CCTE.EMPLID
                      AND WTCTE.WTMAXEFFDT > CCTE.MAXEFFDT
                   )

不在的地方:

;WITH Coverage_CTE (EMPLID, COVERAGE_ELECT, MAXEFFDT)
AS (
    SELECT EMPLID, COUNT(COVERAGE_ELECT), MAX(EFFDT) MAXEFFDT
    FROM PS_SAVINGS_PLAN
    WHERE COVERAGE_ELECT = 'E'
       AND PLAN_TYPE = '49'
    GROUP BY EMPLID
    HAVING COUNT(COVERAGE_ELECT) > 1 
)
, WT_Coverage_CTE (EMPLID, WTMAXEFFDT)
As (
   SELECT EMPLID, MAX(EFFDT) WTMAXEFFDT
   FROM PS_SAVINGS_PLAN
    WHERE COVERAGE_ELECT IN ('W', 'T')
       AND PLAN_TYPE = '49'
    GROUP BY EMPLID
)

SELECT SP.EMPLID, SP.PLAN_TYPE, SP.EFFDT, SP.COVERAGE_ELECT, SP.SAVINGS_COVRG, 
   SP.FLAT_DED_AMT, SP.PCT_GROSS
FROM PS_SAVINGS_PLAN as SP
INNER JOIN Coverage_CTE CCTE on CCTE.EMPLID = SP.EMPLID
WHERE SP.COVERAGE_ELECT = 'E'
   AND PLAN_TYPE = '49'
   AND CCTE.EMPLID NOT IN (SELECT EMPLID
                           FROM WT_Coverage_CTE WTCTE
                           WHERE WTCTE.EMPLID = CCTE.EMPLID
                           AND WTCTE.WTMAXEFFDT > CCTE.MAXEFFDT
                          )

我使用的数据:

declare @PS_SAVINGS_PLAN table (emplid varchar(8), plan_type int,
                      effdt date, coverage_elect varchar(1))

insert into @ps_savings_plan
values
      ('5423H', 49, '2013-01-01', 'W'),
      ('5423H', 49, '2015-10-02', 'E'),
      ('5423H', 49, '2015-10-09', 'T'),
      ('5423H', 49, '2016-09-29', 'E'),
      ('5423H', 49, '2018-10-01', 'E'),
      ('5423H', 49, '2018-10-07', 'T'),
      ('5423n', 49, '2018-10-07', 'E'),
      ('5423n', 49, '2018-10-08', 'E'),
      ('5423H', 49, '2018-11-14', 'W')

【讨论】:

  • 谢谢!这非常有效,感谢您提供几种不同的方法。
猜你喜欢
  • 1970-01-01
  • 2016-11-16
  • 2010-09-15
  • 1970-01-01
  • 2010-12-07
  • 2012-06-23
  • 1970-01-01
  • 1970-01-01
  • 2013-10-19
相关资源
最近更新 更多