我有一个问题根据SQL。数据库是Firebird,但这应该不重要,因为我想尽可能使用ANSI标准。
我必须根据用户资格和用户被分配该资格的日期选择费用(我希望这听起来是正确的)。我有桌子看起来像这样:
Usertable Variables Qualification Rapportcostrate Timeaccount
========= ========= ============= =============== ===========
UserId VarId QuaId RcrId TiaID
UserName VarUserId QuaName RcrName TiaValue
VarQuaId QuaRcrId RcrRate TiaDate
VarValidFrom TiaUserId
我现在需要得到的是:
UserName, RcrRate, TiaValue, TiaDate
我的问题是资格可能随时发生变化,之前输入的资格可能仍然有效。这应该计算(或选择)
RcrRate * TiaValue
基于VarValidFrom
和TiaDate
中的值。我不能把它们放在一起! : - (
我是否清楚自己?希望如此!请随时提出问题!
== 20小时后编辑==
我现在正在使用这个sql命令:
SELECT RcrRate, VarValidFrom, TiaValue FROM USERTABLE
JOIN VARIABLES ON UserId = VarUserId
JOIN QUALIFICATIONS ON VarQuaId = QuaId
JOIN RAPPORTCOSTRATE ON QuaRcrId = RcrId
JOIN TIMEACCOUNT ON UserId = TiaUserId
WHERE UserId = XYZ
现在让我们说表格资格充满了几套
Qualifications Rapportcostrate
=============== ===============
1 Dummy 1 1 Value01 20
2 Testing 2 2 Value02 30
3 Another 3 3 Value03 40
4 FooBar 4 4 Value04 50
如果用户xyz在Variables
中有三个条目,如
Variables
=========
1 1 1 2008-03-01
2 1 2 2009-04-01
3 1 3 2010-05-10
4 1 4 2013-12-12
预期结果应该将符合RcrRate
日期的VarValidFrom
返回TiaDate
。我希望每TiaDate
只收到一行。
......让自己明白......这是一场非常斗争......; - )
答案 0 :(得分:0)
对此有多种解决方案,在下面的解决方案中,我使用CTE(公用表表达式)以逻辑单位分割工作。 cteVarTimes
选择Variables
和Timeaccount
的所有有效组合,然后cteMostRecent
选择用户的最新组合。在主要选择中,我将其与Qualifications
和Rapportcostrate
的信息结合起来。
如果您需要为所有用户返回行,则此解决方案不起作用。在这种情况下,您需要将cteMostRecent
替换为使用每个用户最多VarValidFrom
和TiaDate
的组合选择行的查询。
WITH cteVarTimes AS (
SELECT v.VarUserId as UserId, v.VarQuaId, tia.TiaValue, tia.TiaDate, v.VarValidFrom
FROM Variables v
INNER JOIN Timeaccount tia
ON tia.TiaUserId = v.VarUserId
WHERE tia.TiaDate >= v.VarValidFrom
),
cteMostRecent AS (
SELECT UserId, VarQuaId, TiaValue, VarValidFrom
FROM cteVarTimes
WHERE UserId = 1 -- Parameter in real use
ORDER BY VarValidFrom DESC, TiaDate DESC
ROWS 1
)
SELECT RcrRate, TiaValue, VarValidFrom
FROM cteMostRecent a
INNER JOIN Qualifications q
ON q.QuaId = a.VarQuaId
INNER JOIN Rapportcostrate rcr
ON rcr.RcrId = q.QuaRcrId