我写了一个SQL语句,根据日期参数返回价格列表,但我发现在某些日期,价格丢失了。我正在寻找一种方法来修改此声明以返回指定日期的价格,但如果不可用,则返回指定日期之前可用的最新价格的价格。
Select date, grp, id, price
From
price_table
Where
date In ('12/31/2009', '11/30/2009') And
grp In ('Group1')
例如,我希望能够重新编写上面的语句以返回下面的所有记录,显示所有记录的相应参数日期。假设这是具有每日价格的表的子集,下面的值是所述月份的最后价格。
12/31/2009 Group1 1111 100
12/31/2009 Group1 2222 99
12/29/2009 Group1 3333 98
11/30/2009 Group1 1111 100
11/28/2009 Group1 2222 99
11/30/2009 Group1 3333 98
更新 感谢下面srgerg的一些帮助,我已经能够创建一个一次适用于一个日期的语句,但我仍然希望找到一种方法将多个日期传递给查询。
Select p1.date, p1.grp, p1.id, p1.price
From
price_table As p1 Inner Join
(Select Max(p2.date) As maxdt, id
From
price_table As p2
Where
p2.date <= '12/31/2009'
Group By
p2.id) As p On p.maxdt = p1.date And p1.id = p.id
Where grp in ('Group1')
答案 0 :(得分:2)
您可以尝试这样的事情:
SELECT date, grp, id
, (SELECT TOP 1 price
FROM price_table P2
WHERE P1.id = P2.id
AND P1.grp = P2.grp
AND P2.date <= P1.date
ORDER BY P2.date DESC)
FROM price_table P1
WHERE P1.date IN ('12/31/2009', '11/30/2009')
AND P1.grp IN ('Group1')
修改要获取每个月,组和ID的最后一条记录,您可以尝试这样做:
SELECT date, grp, id, price
FROM price_table P1
WHERE P1.date = (SELECT MAX(date)
FROM price_table P2
WHERE P1.grp = P2.grp
AND P1.id = P2.id
AND YEAR(P1.date) = YEAR(P2.date)
AND MONTH(P1.date) = MONTH(P2.date))
AND P1.grp In ('Group1')
答案 1 :(得分:1)
这是我解决这个问题的方法:
rank = 1
的内容。剧本:
WITH price_grouped AS (
SELECT
date, grp, id, price,
dategrp = CASE
WHEN date <= '11/30/2009' THEN '11/30/2009'
WHEN date <= '12/31/2009' THEN '12/31/2009'
/* extend the list of dates here */
END
FROM price_table
),
price_ranked AS (
SELECT
date, grp, id, price, dategrp,
rank = RANK() OVER (PARTITION BY grp, dategrp ORDER BY date DESC)
FROM price_grouped
)
SELECT date, grp, id, price
FROM price_ranked
WHERE grp IN ('Group1')
AND rank = 1
上述解决方案可能看起来不太方便,因为必须重复每次搜索日期两次。另一种方法可能是将搜索日期列表定义为单独的CTE,并相应地以不同的方式分配日期:
WITH search_dates (Date) AS (
SELECT '11/30/2009' UNION ALL
SELECT '12/31/2009'
/* extend the list of dates here */
),
price_grouped AS (
SELECT
p.date, p.grp, p.id, p.price,
dategrp = MIN(d.Date)
FROM price_table p
INNER JOIN search_dates d ON p.date <= d.Date
GROUP BY
p.date, p.grp, p.id, p.price
),
price_ranked AS (
SELECT
date, grp, id, price, dategrp,
rank = RANK() OVER (PARTITION BY grp, dategrp ORDER BY date DESC)
FROM price_grouped
)
SELECT date, grp, id, price
FROM price_ranked
WHERE grp IN ('Group1')
AND rank = 1
但考虑到前一种解决方案很可能更具性能。