简体   繁体   English

SQL Server 2000-根据其他3列的值从4列表返回单个列值

[英]SQL Server 2000 - Returning a single column value from a 4 column table based on the values of the other 3 columns

I have a table as follows and I want to run a script to return a single PLAN_ID value for each CARE_ID and these are the conditions. 我有一个下表,我想运行一个脚本为每个CARE_ID返回一个PLAN_ID值,这些是条件。 How would I do this? 我该怎么做? I'm writing the script in SQL Server 2005 but it needs to be backwards compatible with SQL Server 2000. 我正在用SQL Server 2005编写脚本,但是它必须与SQL Server 2000向后兼容。

  • If a CARE_ID has only one PLAN_ID then return that PLAN_ID 如果CARE_ID只有一个PLAN_ID则返回该PLAN_ID
  • If a CARE_ID has multiple PLAN_ID s and the value of FIRST_TREATMENT_DATE is NULL then return the highest value PLAN_ID 如果CARE_ID具有多个PLAN_IDFIRST_TREATMENT_DATE值为NULL则返回最大值PLAN_ID
  • If a CARE_ID has multiple PLAN_ID s and the value of FIRST_TREATMENT_DATE is not NULL then return the PLAN_ID which has the most recent date for N5_2_MDT_DATE 如果CARE_ID有多个PLAN_ID S和值FIRST_TREATMENT_DATE不是NULL然后返回PLAN_ID ,其具有最近的日期N5_2_MDT_DATE

My calculations say that the script would return the PLAN_ID values of 我的计算表明该脚本将返回的PLAN_ID

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

Thank you 谢谢

    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

I don't have a 2000 instance handy, but I think I've kept to compatible bits of language. 我没有2000实例,但是我认为我一直使用兼容的语言。 I'm assuming that for the third condition, there won't be two plans with the same N5_2_MDT_DATE . 我假设对于第三个条件,不会有两个具有相同N5_2_MDT_DATE计划。

I actually ran this as a single script with the data setup 1 first and then the query, but am rearranging things so that the actual answer appears first: 实际上,我首先使用数据设置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

You'll note that I've collapsed cases one and two since there's no harm in computing the highest plan number when there's only one plan to consider. 您会注意到,我已经折叠了案例一和案例二,因为在只考虑一个计划的情况下,计算最高计划数没有什么害处。

Also, we disagree on which plan to return for case 106, but I'm certain 96 is correct rather than 67, by the rules you've listed. 此外,我们对案件106的返回计划也意见不一,但根据您列出的规则,我确定96是正确的,而不是67。

The logic is (mostly) all up in the CASE expression in the select. 逻辑(大部分)全部集中在select的CASE表达式中。 If there's only a single row in the group or MAX(FIRST_TREATMENT_DATE) across all rows is NULL (which can only happen if all rows in the group have NULL then we just return the MAX(PLAN_ID) . 如果只有组或单排MAX(FIRST_TREATMENT_DATE)在所有行是NULL (如果该组中的所有行只能发生NULL那么我们只返回MAX(PLAN_ID)

The more complex case is the third. 比较复杂的情况是第三种。 To assist with this, I've got my subquery ( t2 ) which finds the highest N5_2_MDT_DATE value for each CASE_ID . 为了解决这个问题,我有一个子查询( t2 ),它为每个CASE_ID找到最高的N5_2_MDT_DATE值。 We then use this in the ELSE clause of the CASE expression, inside another aggregate - where we try to ensure that we only actually consider a particular PLAN_ID if its N5_2_MDT_DATE column matches the highest one found by t2 - which should only happen once in each group, if the assumption I outlined above in the first paragraph holds. 然后,我们在另一个聚合中的CASE表达式的ELSE子句中使用它-我们试图确保只有在特定PLAN_IDN5_2_MDT_DATE列与t2找到的最高列匹配时,我们才真正考虑它-在每个组中仅应发生一次,如果我在上文第一段中概述的假设成立。

For later versions of SQL Server, CTEs and the ROW_NUMBER() function would make this substantially easier to write, I think. 我认为,对于更高版本的SQL Server,CTE和ROW_NUMBER()函数将使编写起来更加容易。


1 Data setup of the table variable I used. 1我使用的表变量的数据设置。 This should appear first in the query window if you want to run the above query: 如果要运行上述查询,它应该首先出现在查询窗口中:

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'

I'm a bit late but... 我有点晚了,但是...

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何基于SQL Server中当前表列的值使用与其他表不同的列值 - How to use different column values from other table based on value on current table column in SQL server Oracle - 来自单个列的唯一值,但返回其他列 - Oracle - Unique values from a single column, but returning other columns SQL Server 2008基于列值选择表的所有列+来自同一表的列 - SQL Server 2008 Select all columns of a table + a column from the same table based on a column value SQL Server跨其他列的唯一列值(在其他表中) - SQL Server unique column value across other columns (in other table) SQL查询根据同一表中其他列的值更新列 - SQL Query to update a column based on the values of other columns in the same table 根据 SQL Server 中其他列的值在列内进行划分 - Dividing within a column based on values of other columns in SQL Server 从其他表的单个列中返回多个值 - Returning multiple values in single column from other table SQL 服务器 - 根据其他列的值更新一列 - SQL server - Update one column based on the values of other columns 从SQL Server 2000中的两列表中区分出一列 - Distinct of one column from a two column table in SQL Server 2000 根据同一个表中其他列的值为列分配值 - Assign value to a column based on values of other columns in the same table
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM