1

我有以下示例表:

ID    Type    Price    Code    Date
 1      1       .99    Null    6/1
 2      2      1.99    Null    5/1
 3      1       .99    1234    4/1
 4      3      1.99    Null    5/1
 5      2      3.99    Null    6/1
 6      1      1.30    1234    5/1
 7      1      1.64    5673    6/10

我需要选择以下内容:类型、价格 - 基于以下规则的所有类型:

  1. 如果代码与请求匹配,则获取最近的记录。
  2. 如果一个类型的所有代码都为空,则取最近的记录。

因此,代码为“1234”的请求的结果集应该是:

ID:
4 (This is the most recent record for type 3)
5 (This is the most recent record for type 2)
6 (This is the most recent record for type 1 having a code = '1234')

我创建了以下查询:

Select distinct 
    ID, Type, Price, Code, Date 
from 
    tblPRODUCT 
where 
    Code = '1234' OR Date IN (Select MAX(Date) from tblPRODUCT Group By Type)

但这并没有给我正确的结果。想法?

4

3 回答 3

2
Select 
    ID, Type, Price, Code, Date 
from 
    tblPRODUCT tbpr
where 
    (Code = '1234' AND Date IN (Select MAX(Date) from tblPRODUCT where type= tbpr.type   
and code = '1234'))
OR Date IN (Select MAX(Date) from tblPRODUCT where type= tbpr.type 
         and not exists(select code from tblPRODUCT where type= tbpr.type  and code is 
not null) ) 

这是如何运作的 :

如果代码匹配,Ored 条件的第一部分将选择行。请注意,如果有多行匹配相同 id 的代码,它会选择具有最大日期的行。

如果所有代码都为空,则第二个 Ored 条件将选择具有最大日期的行。

我对其进行了测试,它适用于您的采样数据,并且适用于您尝试的任何数据组合。

SQLFIDDLE:

http://www.sqlfiddle.com/#!3/19b03/18

于 2013-06-23T17:19:01.983 回答
1

迟到且类似于已删除的答案,但只是为了展示比接受的答案稍微简单的方法;

WITH cte AS (
  SELECT *, 
  ROW_NUMBER() OVER(PARTITION BY Type ORDER BY Code DESC, Date DESC) rn
  FROM tblPRODUCT WHERE Code='1234' OR Code IS NULL
)
SELECT ID, Type, Price, Code, Date
FROM cte WHERE rn=1;

一个用于测试的 SQLfiddle

于 2013-06-23T21:00:06.523 回答
0

想了一会儿,这似乎相当复杂。您没有给定代码上所有类型的记录,因此您必须以某种方式生成它们。这建议使用驱动程序表。

然后,优先规则使这有点复杂:

select coalesce(p.id, driver.id) as id,
       coalesce(p.[type], driver.[type]) as [type],
       coalesce(p.price, driver.price) as price,
       coalesce(p.code, driver.code) as code,
       coalesce(p.[date], driver.[date]) as [date]
from (select p.*
      from (select p.*, row_number() over (partition by [type]
                                           order by (case when [type] is NULL then 1 else 0 end) desc,
                                                    [date]
                                          ) as seqnum
            from tblProduct p
           ) p
       where seqnum = 1
     ) driver left outer join
     tblProduct p
     on p.code = XXX and
        p.type = driver.[type] and
        driver.type is NULL

类似的方法是用来union all获取值:

select ID, Type, Price, Code, Date
from tblProduct p
where date = (select max(date) from tblProduct p2 where p2.code = p.code and p2.type = p.type) and
      code = XXX
union all
select id, type, price, code, Date
from tblProduct p
where code is null and
      date = (select max(date) from tblProduct p2 where p2.code = p.code and p2.type is null) and
      type not in (select type from tblProduct p2 where p2.code = p.code)

我意识到 SQL 代码看起来非常不同。但类似的想法是,您必须将 NULL 代码的值与您正在查找的代码分开获取。第一个使用驱动程序表,然后在select. 第二个做 a union all,将两组分成两个不同的组。

于 2013-06-23T17:00:41.663 回答