oJM*_*86o 6 t-sql sql-server-2005
我有一个ExchangeRates表,它有一个countryid和一个exchangerate,这个效果:
ExchangeRateID Country ToUSD ExchangeRateDate
1 Euro .7400 2/14/2011
2 JAP 80.1900 2/14/2011
3 Euro .7700 7/20/2011
Run Code Online (Sandbox Code Playgroud)
请注意,根据日期,可能会有相同的国家/地区具有不同的费率...因此,例如,在2011年2月14日欧元为0.7400,现在是.7700 7/20/2011.
我有另一个行项目表,用于根据国家/地区列出项目.在此表中,每个行项目都有一个与之关联的日期.订单项日期应根据汇率使用相应的日期和国家/地区.因此,如果我在2011年2月16日有一个国家/地区欧元的订单项,则使用上述数据时,应使用2011年2月14日的欧元值而不是7/20/2011的值,因为日期(条件er. ExchangeRateDate <= erli.LineItemDate).如果我在表中只有一个项目,但是假设我的订单项日期为8/1/2011那么这个条件(er.ExchangeRateDate <= erliLineItemDate)将返回多行,因此我的查询将失败...
SELECT
er.ExchangeRateID,
er.CountryID AS Expr1,
er.ExchangeRateDate,
er.ToUSD,
erli.ExpenseReportLineItemID,
erli.ExpenseReportID,
erli.LineItemDate
FROM
dbo.ExpenseReportLineItem AS erli
LEFT JOIN
dbo.ExchangeRate AS er
ON er.CountryID = erli.CountryID
AND DATEADD(d, DATEDIFF(d, 0, er.ExchangeRateDate), 0) <= DATEADD(d, DATEDIFF(d, 0,
erli.LineItemDate), 0)
WHERE (erli.ExpenseReportID = 196)
Run Code Online (Sandbox Code Playgroud)
这个左连接的问题是因为日期是<=行项目日期所以它返回许多记录,我不得不以某种方式做到这一点,但不知道如何.
LineItem表有多个记录,每个记录可以有自己的CountryID:
Item Country ParentID LineItemDate
Line Item 1 Euro 1 2/14/2011
Line Item 2 US 1 2/14/2011
Line Item3 Euro 1 2/15/2011
Run Code Online (Sandbox Code Playgroud)
所以ParentID(ExpenseReportID)= 1有三条记录.那么我拿这些记录并加入ExchangeRate表,其中我的行项目表中的国家/地区=汇率表的国家/地区(该部分很容易)但是第二个条件我要做的是:
AND DATEADD(d, DATEDIFF(d, 0, er.ExchangeRateDate), 0) <= DATEADD(d, DATEDIFF(d, 0,
erli.LineItemDate), 0)
Run Code Online (Sandbox Code Playgroud)
但问题出在这里是因为这将从我的汇率表中返回多行,因为欧元列出了两次.
我可能在这里遗漏了一些东西,但据我了解,您的问题的“愚蠢”解决方案是使用 ROW_NUMBER 函数和外部过滤器与现有的“返回太多条目”查询(这也可以通过 CTE 来完成,但是对于像这样的简单情况,我更喜欢派生表语法):
SELECT *
FROM (
SELECT
er.ExchangeRateID,
er.CountryID AS Expr1,
er.ExchangeRateDate,
er.ToUSD,
erli.ExpenseReportLineItemID,
erli.ExpenseReportID,
erli.LineItemDate,
ROW_NUMBER() OVER (PARTITION BY ExpenseReportID, ExpenseReportLineItemID ORDER BY ExchangeRateDate DESC) AS ExchangeRateOrderID
FROM dbo.ExpenseReportLineItem AS erli
LEFT JOIN dbo.ExchangeRate AS er
ON er.CountryID = erli.CountryID
AND DATEADD(d, DATEDIFF(d, 0, er.ExchangeRateDate), 0)
<= DATEADD(d, DATEDIFF(d, 0, erli.LineItemDate), 0)
WHERE (erli.ExpenseReportID = 196)
--For reasonable performance, it would be VERY nice to put a filter
-- on how far back the exchange rates can go here:
--AND er.ExchangeRateDate > DateAdd(Day, -7, GetDate())
) As FullData
WHERE ExchangeRateOrderID = 1
Run Code Online (Sandbox Code Playgroud)
抱歉,如果我误解了,否则希望这会有所帮助!
| 归档时间: |
|
| 查看次数: |
203 次 |
| 最近记录: |