我有一张表格如下
Rate Effective_Date
---- --------------
5.6 02/02/2009
5.8 05/01/2009
5.4 06/01/2009
5.8 12/01/2009
6.0 03/15/2009
我应该找到对当前日期和之后有效的所有费率。因此,为了获得当前有效率,我使用
SELECT TOP 1 * from table
where effective_date < '05/05/2009'
order by effective date desc
查询当前日期之后的费率
SELECT * from table
where effective_date > '05/05/2009'
要结合这两个结果,我使用了一个联合作为
SELECT TOP 1 * from table
where effective_date < '05/05/2009'
order by effective date desc
UNION
SELECT * from table
where effective_date > '05/05/2009'
预期结果是
Rate Effective Date
---- --------------
5.8 05/01/2009
5.4 06/01/2009
5.8 12/01/2009
6.0 03/15/2009
但我得到实际结果为
Rate Effective Date
---- --------------
5.6 02/02/2009
5.4 06/01/2009
5.8 12/01/2009
6.0 03/15/2009
我不清楚为什么会这样?有什么建议吗?
答案 0 :(得分:26)
它的工作原理如下:
select *
from (
select top 1 *
from table
where effective_date <= '05/05/2009'
order by effective_date desc
) as current_rate
union all
select *
from table
where effective_date > '05/05/2009'
答案 1 :(得分:8)
忽略了作为联合一部分的select语句中的Order By。因此,您的TOP 1正在选择一些仲裁记录(可能是该表的聚簇键的第一条记录)。
答案 2 :(得分:3)
与联盟一起使用时,排序依据无效...
我使用Common Table Expression和一些Rank和Case语句技巧来制作一个快速而又脏的东西来获得你想要的结果..
WITH CTE_RATES ( RATE, EFFECTIVE_DATE, CUR, SORT )
AS (
SELECT
Rate,
Effective_date,
CASE WHEN Effective_date > '5/5/2009' THEN 1
ELSE 0
END,
RANK() OVER (PARTITION BY
CASE WHEN EFFECTIVE_DATE > '5/5/2009' THEN 1
ELSE 0
END
ORDER BY EFFECTIVE_DATE DESC)
FROM TestTable
)
SELECT RATE, EFFECTIVE_DATE
FROM (
SELECT RATE, EFFECTIVE_DATE
FROM CTE_RATES
WHERE CUR = 0 AND SORT = 1
UNION ALL
SELECT RATE, EFFECTIVE_DATE
FROM CTE_RATES
WHERE CUR = 1
) AS QRY
ORDER BY EFFECTIVE_DATE
解释发生了什么......
CTE定义从查询返回的速率,日期,当前和排序标志......
CASE将结果分为搜索日期之前的结果和搜索日期之后的结果。我们使用联合中案例(Cur)的结果从分区列表中提取结果。
然后,Rank()函数通过在CASE语句用于分隔列表的相同条件下创建分区来对列表进行排序。然后我们按降序方式按生效日期排序。这将采用“过去”列表并使其成为最新的“过去”条目等级1 ..
然后在查询的union部分..
在顶部,我们从“过去”列表(cur = 0)和“过去”列表中的第一个条目获得排名和日期..(sort = 1)..将返回1记录(如果搜索日期之前没有记录,则为0)..
然后我们将其与“当前”列表中的所有记录(cur = 1)联合起来
然后最后..我们取得UNION的结果..并在生效日期之前命令我们提供所有当前记录,以及“最新”以前的记录。
答案 3 :(得分:1)
我相信上述查询不包括05/01/2009使用&lt;和&gt;而不是&lt; =和&gt; =。