我的SQL体验相当小,所以请在这里轻松点我。我有一个表tblForEx
,我正在尝试创建一个查询特定列LastSalesRateChangeDate
和ForExRate
的查询。
基本上我要做的是让查询检查LastSalesRateChangeDate
,然后拉出同一行的ForExRate
(显然在ForExRate
列中),然后我需要检查自上次LastSalesRateChangeDate
更改以来是否有+/- 5%的变化。我希望这是有道理的,我试图尽可能清楚地解释它。
我相信我需要创建一个'子查询'来查看LastSalesRateChangeDate
并从那个日期开始提取ForEx
费率,但我只是不知道该怎么做。< / p>
我应该在Access(SQL)
中添加这个示例数据,这是表格的样子:
| BaseCur | ForCur | ForExRate | LastSalesRateChangeDate
| USD | BRL | 1.718 | 12/9/2008
| USD | BRL | 1.65 | 11/8/2008
所以我需要一个查询来查看LastSalesRateChangeDate
列,检查日期是否已更改,如果是,请取ForExRate
值,然后给出{{1}的百分比差异自上一条记录以来的值。
所以最终结果可能看起来像
ForExRate
答案 0 :(得分:1)
戈登的回答指出了正确的方向:
SELECT t2.*, (SELECT top 1 t.ForExRate
FROM tblForEx t
where t.BaseCur=t2.BaseCur AND t.ForCur=t2.ForCur and t.LastSalesRateChangeDate<t2.LastSalesRateChangeDate
order by t.LastSalesRateChangeDate DESC, t.ForExRate DESC
) AS PreviousRate, [ForExRate]/[PreviousRate]-1 AS ChangeRatio
FROM tblForEx AS t2;
Access会在子查询中的TOP 1
导致“关联”时出错。我们打破了关系,因此通过在ORDER BY
子句中添加一个额外的项来消除错误。要使比率显示为百分比,请切换到设计视图并相应地更改该列的属性。
答案 1 :(得分:0)
如果我理解正确,您需要以前的值。在MS Access中,您可以使用相关子查询:
select t.*,
(select top (1) t2.LastSalesRateChangeDate
from tblForEx as t2
where t2.BaseCur = t.BaseCur and t2.ForCur = t.ForCur
t2.LastSalesRateChangeDate < t.LastSalesRateChangeDate
order by t2.LastSalesRateChangeDate desc
) as prev_LastSalesRateChangeDate
from t;
现在,将此作为子查询,您可以使用join
获取以前的汇率:
select t.*, ( (t.ForExRate / tprev.ForExRate) - 1) as change_ratio
from (select t.*,
(select top (1) t2.LastSalesRateChangeDate
from tblForEx as t2
where t2.BaseCur = t.BaseCur and t2.ForCur = t.ForCur
t2.LastSalesRateChangeDate < t.LastSalesRateChangeDate
order by t2.LastSalesRateChangeDate desc
) as prev_LastSalesRateChangeDate
from t
) as t inner join
tblForEx as tprev
on tprev.BaseCur = t.BaseCur and tprev.ForCur = t.ForCur
tprev.LastSalesRateChangeDate = t.prev_LastSalesRateChangeDate;
答案 2 :(得分:0)
根据我的理解,您可以使用LEAD功能通过使用以下查询获取新列中的最后更改日期费率:
WITH CTE AS (
SELECT *, LEAD(ForExRate, 1) OVER(PARTITION BY BaseCur, ForCur ORDER BY LastChangeDate DESC) LastValue
FROM #TT
)
SELECT BaseCur, ForCur, ForExRate, LastChangeDate , CAST( ((ForExRate - ISNULL(LastValue, 0))/LastValue)*100 AS float)
FROM CTE
问题在于:
对于组中的每一行,您将使用LEAD函数创建新的计算列。
如果特定的BaseCur和ForCur只有一行,那么列中也会有NULL。
分辨率: 如果您确定每个BaseCur和ForCur至少有两行,那么您可以使用WHERE子句删除最终结果中的NULL值。
WITH CTE AS (
SELECT *, LEAD(ForExRate, 1) OVER(PARTITION BY BaseCur, ForCur ORDER BY LastChangeDate DESC) LastValue
FROM #TT
)
SELECT BaseCur, ForCur, ForExRate, LastChangeDate , CAST( ((ForExRate - ISNULL(LastValue, 0))/LastValue)*100 AS float) Percentage
FROM CTE
WHERE LastValue IS NOT NULL
答案 3 :(得分:0)
SELECT basetbl.BaseCur, basetbl.ForCur, basetbl.NewDate, basetbl.OldDate, num2.ForExRate/num1.ForExRate*100 AS PercentChange FROM
(((SELECT t.BaseCur, t.ForCur, MAX(t.LastSalesRateChangeDate) AS NewDate, summary.Last_Date AS OldDate
FROM (tblForEx AS t
LEFT JOIN (SELECT TOP 2 BaseCur, ForCur, MAX(LastSalesRateChangeDate) AS Last_Date FROM tblForEx AS t1
WHERE LastSalesRateChangeDate <>
(SELECT MAX(LastSalesRateChangeDate) FROM tblForEx t2 WHERE t2.BaseCur = t1.BaseCur AND t2.ForCur = t1.ForCur)
GROUP BY BaseCur, ForCur) AS summary
ON summary.ForCur = t.ForCur AND summary.BaseCur = t.BaseCur)
GROUP BY t.BaseCur, t.ForCur, summary.Last_Date) basetbl
LEFT JOIN tblForEx num1 ON num1.BaseCur=basetbl.BaseCur AND num1.ForCur = basetbl.ForCur AND num1.LastSalesRateChangeDate = basetbl.OldDate))
LEFT JOIN tblForEx num2 ON num2.BaseCur=basetbl.BaseCur AND num2.ForCur = basetbl.ForCur AND num2.LastSalesRateChangeDate = basetbl.NewDate;
这使用了一系列子查询。首先,您要选择BaseCur和ForCur的最新日期。然后,您将加入上一个日期。我这样做是通过使用另一个子查询来选择前两个日期,并排除一个等于先前建立的最近日期的日期。这是&#34;摘要&#34;子查询。
然后,您将在&#34; basetbl&#34;中获得BaseCur,ForCur,NewDate和OldDate。子查询。之后,将原始表格的两个简单连接返回到这些日期,以获得适用的速率。
最后,您正在选择BaseCur,ForCur以及您要用于计算费率变化的任何公式。我在那个中使用了一个简单的比例,但它很容易改变。如果需要,您可以删除第一行中的日期,它们仅作为参考点。
它看起来并不漂亮,但复杂的Access SQL查询永远不会。