2012-04-05 130 views
-1

我有一个3列的表。 下面是一个只有几个演示条目的例子。该表格表示物品价格变化的日期。我需要一个查询来告诉我特定日期的所有商品的价格。具体日期可能在价格变化之间。在午夜的价格变化,所以变化之日起,就是价格从那时起直到与当日之前的变化前:需要基本的SQL查询帮助

itemCode datePriceEffective price 
AB   2012-01-01   9.99 
AB   2012-03-02   10.50 
XY   2011-09-20   34.99 

我希望得到所有的物品价格给定日期。每个日期都没有条目,只是价格变化的日期。 所以2012-03-05会回来

AB 10.50 
XY 34.99 

和2012-02-27将返回:

得到这个逃脱我需要
AB 9.99 
XY 34.99 

的SQL查询。解决赞赏。

编辑为答案会发生错误的方向请参阅斜体的编辑。之后更多信息

+0

你有使用日期另一列?因为您在查询中提到的日期不会在任何列中看到。 – Virus 2012-04-05 10:20:09

回答

1

您将需要加入回表如下:

declare @effdate datetime 
set @effdate = CONVERT(datetime,'2012-02-27') 

;WITH CTE_DATA as (
    select itemCode='AB', datePriceEffective = CONVERT(Datetime,'2012-01-01'), price = 9.99 
    union all select itemCode='AB', datePriceEffective = CONVERT(Datetime,'2012-03-02'), price = 10.50 
    union all select itemCode='XY', datePriceEffective = CONVERT(Datetime,'2011-09-20'), price = 34.99 
) 
select 
    d.itemcode, 
    price 
from 
    CTE_DATA d 
    join (
     select 
      itemcode, 
      effdate = MAX(datepriceeffective) 
     from CTE_DATA sub where sub.datepriceeffective <= @effdate 
     group by itemcode 
    ) x 
     on x.itemCode = d.itemCode 
     and x.effdate = d.datePriceEffective 

注意,CTE只是在这个例子中,你应该将其交换为您的真正的表。

UPDATE:另一种方法是使用ROW_NUMBER和分区如下:

SELECT   
    itemcode, 
    price 
FROM  
    (
     SELECT 
      itemcode, 
      price, 
      rowno = ROW_NUMBER() over (partition by itemcode order by datePriceEffective desc) 
     from 
      CTE_DATA 
      where datePriceEffective <= @effdate 
    ) x 
where 
    rowno = 1 

(替代这次选择了一个在前面的查询尝试它的数据)

+0

这看起来很复杂。 – 2012-04-05 10:26:57

+0

CTE只是为了生成一些数据来运行。实际的查询很简单。尼古拉的解决方案与我的第二个答案类似,但更加整齐地过滤了所需的结果。 – 2012-04-05 10:49:48

+1

标记为接受的答案,因为这是第一次工作。其他一些人也工作 – 2012-04-05 10:53:57

2
SELECT itemCode,price FRom TableNameHere WHERE datePriceEffective <= '2012-03-05' 

编辑 - 一个“简单”的答案,希望可以很容易地遵循。

你得到thelatest日期是在所需的日期范围内是有效的项目,然后加入表本身得到的价格在该日期

SELECT t1.itemCode,t1.price FROM 
    (
    SELECT itemCode,MAX(datePriceEffective) AS datePriceEffective 
    FROM TableNameHere 
    WHERE datePriceEffective <= '2012-03-05' 
) a 
INNER JOIN TableNameHere t1 ON t1.itemCode = a.itemCode AND t1.datePriceEffective = a.datePriceEffective 
+0

这不可能是正确的,那天没有条目! – 2012-04-05 10:16:13

+0

对不起,是你在你的问题中列出了那个日期,然后编辑你的问题,以解释你的后... – 2012-04-05 10:24:51

+0

提供datePriceEffective是一个日期时间列,你可以使用小于和大于运营商。 – 2012-04-05 10:26:46

0

假设你有一个名为另一列“ GivenDate',下面是查询。

SELECT itemCode, price 
FROM tblName 
WHERE GivenDate= '2012-03-05' 
+0

我没有另一列 – 2012-04-05 10:23:03

+0

您是否必须使用datePriceEffective列来获取给定日期的结果?并且datePriceEffective经常更新? – Virus 2012-04-05 10:24:26

+0

如果是这种情况,那么您可以查询datePriceEffective列中的日期。你不能使用任何'其他'给定的日期。 – Virus 2012-04-05 10:25:43

1
declare @date datetime = '2012-03-05' 

select distinct itemcode, 
    (
     select top(1) itemprice 
     from mytable mt2 
     where 
      mt1.itemcode = mt2.itemcode and 
      mt2.datepriceeffective <= @date 
     order by datepriceeffective desc 
    ) as itemprice 
from 
    mytable mt1 
where 
    datepriceeffective <= @date 
+0

这工作谢谢。虽然不是第一次,所以错过了接受。 – 2012-04-05 10:54:31

3

这会按照每个itemCode的datePriceEffective降序检索第一条记录。

select top 1 with ties * 
from ATable 
where datePriceEffective <= @givenDate 
order by row_number() over (partition by itemCode 
          order by datePriceEffective desc) 
+0

+1:这是'WITH TIES'的一个很好的用法 - 提供了一个非常好的解决方案! – 2012-04-05 10:40:29

+0

这个作品谢谢。虽然不是第一次,所以错过了接受。 – 2012-04-05 10:55:28

1
SELECT b.itemCode, 
(SELECT Price FROM dbo.tblProducts a WHERE datePriceEffective = 
(SELECT MAX(a.datePriceEffective) FROM dbo.tblProducts a WHERE a.itemCode = b.itemCode)) AS Price 
FROM dbo.tblProducts b 
WHERE b.datePriceEffective <= '2012-03-05' 
GROUP BY b.itemCode 

我已经测试了!它会给你最新的价格为每个项目

0

这适用于SQL2000

SELECT  s.itemCode 
      , (SELECT  TOP 1 price 
       FROM  #MyTable 
       WHERE  itemCode = s.itemCode 
          AND datePriceEffective < @SearchDate) AS price 
FROM  (
      SELECT DISTINCT itemCode 
      FROM #MyTable 
      ) s