【问题标题】:SQL Server 2000 - Returning a single column value from a 4 column table based on the values of the other 3 columnsSQL Server 2000 - 根据其他 3 列的值从 4 列表中返回单列值
【发布时间】:2014-02-13 22:43:33
【问题描述】:

我有一个如下表,我想运行一个脚本来为每个 CARE_ID 返回一个 PLAN_ID 值,这些是条件。我该怎么做?我在 SQL Server 2005 中编写脚本,但它需要向后兼容 SQL Server 2000。

  • 如果CARE_ID 只有一个PLAN_ID,则返回PLAN_ID
  • 如果一个CARE_ID有多个PLAN_IDs并且FIRST_TREATMENT_DATE的值为NULL则返回最大值PLAN_ID
  • 如果CARE_ID 有多个PLAN_IDs 并且FIRST_TREATMENT_DATE 的值不是NULL,则返回PLAN_ID,它的最近日期为N5_2_MDT_DATE

我的计算表明脚本将返回

PLAN_ID
1833,65,162,2929,67,93,44,1136,1046,1047,1048,1049,1050,1052,1870,2426

谢谢

    PLAN_ID CARE_ID N5_2_MDT_DATE       FIRST_TREATMENT_DATE
    1833    1       20/08/2011 00:00    NULL
    199     1       23/06/2010 00:00    NULL
    65      4       27/11/2009 00:00    NULL
    162     5       30/07/2010 00:00    NULL
    54      5       15/11/2009 00:00    NULL
    55      5       29/10/2009 00:00    NULL
    63      5       03/09/2009 00:00    NULL
    2929    9       29/01/2013 00:00    NULL
    99      9       08/03/2010 00:00    NULL
    95      9       04/02/2010 00:00    NULL
    64      9       18/11/2009 00:00    NULL
    67      106     14/01/2013 00:00    NULL
    96      106     20/07/2009 00:00    NULL
    93      107     23/02/2010 00:00    21/09/2012 00:00
    44      108     25/12/2009 00:00    NULL
    43      108     07/10/2009 00:00    NULL
    1136    364     18/02/2011 00:00    19/02/2011 00:00
    1122    364     26/01/2011 00:00    19/02/2011 00:00
    1046    1661    25/01/2011 00:00    25/01/2011 00:00
    1047    1662    25/01/2011 00:00    25/01/2011 00:00
    1048    1663    25/01/2011 00:00    01/02/2011 00:00
    1049    1665    25/01/2011 00:00    NULL
    1050    1666    23/01/2011 00:00    01/02/2011 00:00
    1052    1667    01/02/2011 00:00    01/02/2011 00:00
    1870    1781    04/10/2010 00:00    10/02/2011 00:00
    1869    1781    04/10/2010 00:00    10/02/2011 00:00
    1868    1781    04/10/2010 00:00    10/02/2011 00:00
    2426    2246    23/03/2012 00:00    01/07/2012 00:00
    2275    2246    01/01/2012 00:00    01/07/2012 00:00
    2170    2246    14/10/2011 00:00    01/07/2012 00:00
    1784    2246    04/08/2011 00:00    01/07/2012 00:00
    1940    2246    10/07/2011 00:00    01/07/2012 00:00
    1637    2246    20/06/2011 00:00    01/07/2012 00:00
    1539    2246    02/06/2011 00:00    01/07/2012 00:00
    1538    2246    01/06/2011 00:00    01/07/2012 00:00
    1536    2246    31/05/2011 00:00    01/07/2012 00:00

【问题讨论】:

  • 单个CARE_ID 是否可以有一些行带有NULL FIRST_TREATMENT_DATE 和其他行非NULL?并且(不影响这个问题)他们可以有不同的FIRST_TREATMENT_DATE 值吗?
  • @Damien_The_Unbeliever - FIRST_TREATMENT_DATE 的值基于 CARE_ID,因此这些值只会全为 NULL 或全为相同的日期,而 N5_2_MDT_DATE 的值基于 PLAN_ID。希望这可以验证。谢谢。

标签: sql sql-server-2005 sql-server-2000


【解决方案1】:

我手边没有 2000 实例,但我认为我一直使用兼容的语言。我假设对于第三种情况,不会有两个具有相同 N5_2_MDT_DATE 的计划。

我实际上将其作为单个脚本运行,首先是数据设置1,然后是查询,但我正在重新安排事情,以便首先出现实际答案:

select t1.CARE_ID,
    CASE
        --Cases one and two are identical, effectively
        WHEN COUNT(*) = 1 OR MAX(t1.FIRST_TREATMENT_DATE) IS NULL
                 THEN MAX(t1.PLAN_ID)
        ELSE MAX(CASE WHEN t1.N5_2_MDT_DATE = t2.LastDate THEN t1.PLAN_ID END)
    END
from @t t1
    inner join
    (select CARE_ID,MAX(N5_2_MDT_DATE) as LastDate
    from @t
    group by CARE_ID
    ) t2
        on t1.CARE_ID = t2.CARE_ID
group by t1.CARE_ID

您会注意到,我已经折叠了案例一和案例二,因为当只考虑一个计划时,计算最高计划号并没有什么坏处。

此外,我们不同意返回案例 106 的哪个计划,但根据您列出的规则,我确定 96 是正确的,而不是 67。

逻辑(大部分)都在选择中的CASE 表达式中。如果组中只有一行或所有行中的MAX(FIRST_TREATMENT_DATE)NULL(仅当组中的所有行都具有NULL 时才会发生这种情况,那么我们只返回MAX(PLAN_ID)

更复杂的情况是第三种。为了帮助解决这个问题,我有我的子查询 (t2),它为每个 CASE_ID 找到最高的 N5_2_MDT_DATE 值。然后,我们在 CASE 表达式的 ELSE 子句中使用它,在另一个聚合内 - 我们尝试确保我们仅在其 N5_2_MDT_DATE 列与 @987654335 找到的最高列匹配时才实际考虑特定的 PLAN_ID @ - 如果我在上面第一段中概述的假设成立,那么每个组中应该只发生一次。

我认为,对于更高版本的 SQL Server,CTE 和 ROW_NUMBER() 函数将使这更容易编写。


1 我使用的表变量的数据设置。如果您想运行上述查询,这应该首先出现在查询窗口中:

declare @t table (PLAN_ID int not null, CARE_ID int not null,
      N5_2_MDT_DATE datetime not null,FIRST_TREATMENT_DATE datetime null)
insert into @t(PLAN_ID,CARE_ID,N5_2_MDT_DATE,FIRST_TREATMENT_DATE)
SELECT 1833, 1    ,'20110820',NULL        union all
SELECT 199 , 1    ,'20100623',NULL        union all
SELECT 65  , 4    ,'20091127',NULL        union all
SELECT 162 , 5    ,'20100730',NULL        union all
SELECT 54  , 5    ,'20091115',NULL        union all
SELECT 55  , 5    ,'20091029',NULL        union all
SELECT 63  , 5    ,'20090903',NULL        union all
SELECT 2929, 9    ,'20130129',NULL        union all
SELECT 99  , 9    ,'20100308',NULL        union all
SELECT 95  , 9    ,'20100204',NULL        union all
SELECT 64  , 9    ,'20091118',NULL        union all
SELECT 67  , 106  ,'20130114',NULL        union all
SELECT 96  , 106  ,'20090720',NULL        union all
SELECT 93  , 107  ,'20100223','20120921'  union all
SELECT 44  , 108  ,'20091225',NULL        union all
SELECT 43  , 108  ,'20091007',NULL        union all
SELECT 1136, 364  ,'20110218','20110219'  union all
SELECT 1122, 364  ,'20110126','20110219'  union all
SELECT 1046, 1661 ,'20110125','20110125'  union all
SELECT 1047, 1662 ,'20110125','20110125'  union all
SELECT 1048, 1663 ,'20110125','20110201'  union all
SELECT 1049, 1665 ,'20110125',NULL        union all
SELECT 1050, 1666 ,'20110123','20110201'  union all
SELECT 1052, 1667 ,'20110201','20110201'  union all
SELECT 1870, 1781 ,'20101004','20110210'  union all
SELECT 1869, 1781 ,'20101004','20110210'  union all
SELECT 1868, 1781 ,'20101004','20110210'  union all
SELECT 2426, 2246 ,'20120323','20120701'  union all
SELECT 2275, 2246 ,'20120101','20120701'  union all
SELECT 2170, 2246 ,'20111014','20120701'  union all
SELECT 1784, 2246 ,'20110804','20120701'  union all
SELECT 1940, 2246 ,'20110710','20120701'  union all
SELECT 1637, 2246 ,'20110620','20120701'  union all
SELECT 1539, 2246 ,'20110602','20120701'  union all
SELECT 1538, 2246 ,'20110601','20120701'  union all
SELECT 1536, 2246 ,'20110531','20120701'

【讨论】:

  • Damien_The_Unbeliever - 太好了,感谢您花时间和精力到达那里!
【解决方案2】:

我来晚了,但是……

select Care_ID, 
case when d.b is null then MAx(Plan_ID) else (select Distinct data.Plan_ID
                                              from 
                                                 (select max(N5_2_MDT_DATE) as N5_2_MDT_DATE
                                                  from data 
                                                  group by CARE_ID) a 
                                              inner join data on data.N5_2_MDT_DATE = a.N5_2_MDT_DATE
                                              Where d.Care_ID = data.Care_ID

 ) End as Plan_ID
from 
(
   select PLAN_ID, CARE_ID, Max(N5_2_MDT_DATE) as a, Max(FIRST_TREATMENT_DATE) as b
   from data
   group by   PLAN_ID, CARE_ID     
  ) d    
Group by CARE_ID, d.b

演示:http://sqlfiddle.com/#!3/834f6/53

【讨论】:

    猜你喜欢
    • 2019-04-17
    • 2016-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    相关资源
    最近更新 更多