Pergunta

Eu tenho uma tabela como abaixo

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

eu deveria encontrar as todas as taxas que são eficazes para a data atual e depois dela. Assim, para obter a taxa efetiva atual, eu uso

SELECT TOP 1 * from table 
where effective_date < '05/05/2009' 
order by effective date desc

para as taxas depois da data atual a consulta é

SELECT * from table 
where effective_date > '05/05/2009'

Para combinar esses dois resultado eu uso uma união como

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'

O resultado esperado é

Rate Effective Date
---- --------------
5.8  05/01/2009
5.4  06/01/2009
5.8  12/01/2009
6.0  03/15/2009

Mas eu recebo o resultado real como

Rate Effective Date
---- --------------
5.6  02/02/2009
5.4  06/01/2009
5.8  12/01/2009
6.0  03/15/2009

Eu não tenho a menor idéia de por que isso acontece? Alguma sugestão?

Foi útil?

Solução

Ele funciona da seguinte maneira:

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'

Outras dicas

A Ordem por em uma instrução SELECT que faz parte de uma união é ignorado. Daí o seu TOP 1 está selecionando algum registro arbitrário (provavelmente o primeiro registro pela chave de cluster para a tabela).

Order By é inválido quando usado com uma União ...

Eu trabalhei até uma rapidinha e sujo coisinha usando Common Table Expression com algum Rank e caso declaração truques para obter os resultados que você estava procurando ..

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

Para explicar o que está acontecendo ...

O CTE define a taxa, data, bandeiras atuais e de classificação retornados da consulta ...

O caso separa os resultados em aqueles que são anteriores à data de pesquisa, e aqueles que são após a data de pesquisa .. Nós usamos os resultados do caso (CUR) em nossa união para puxar os resultados da lista particionado. .

função

O Rank (), em seguida, classifica a lista criando uma partição nos mesmos critérios que os usos instrução case para separar a lista .. então nós ordem até a data efetiva em ordem decrescente de moda. Isso levará a lista "passado" e torná-lo é mais atual "passado" rank entrada 1 ..

Em seguida, na parte da união da consulta ..

Na parte superior, estamos recebendo a classificação ea data a partir da lista "passado" (cur = 0) e a primeira entrada na lista de "passado" .. (sort = 1) .. que irá retornar 1 registro (ou 0 se não há registros que são anteriores à data de busca) ..

Então nós união que com todo o registro da lista "atual" (cur = 1)

Então, finalmente .. tomamos os RESULTADOS DA UNIÃO .. e para que até a data efetiva nos dando todos os registros atuais, e o recorde anterior "mais atual".

Eu acredito que as consultas acima estão excluindo 05/01/2009 usando em vez de <= e> =.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top