SQL UNION с ORDER

Что не так с этим заявлением? Я получаю следующие ошибки:

Сообщение 156, уровень 15, состояние 1, строка 4 Неверный синтаксис рядом с ключевым словом «ЗАКАЗ».

Сообщение 156, уровень 15, состояние 1, строка 9 Неверный синтаксис рядом с ключевым словом «ЗАКАЗ».

(SELECT TOP 1 dbo.ZERORATES.Maturity_Date AS Date1, dbo.ZERORATES.Zero_Rate AS Rate1
    FROM dbo.ZERORATES
    WHERE dbo.ZERORATES.Maturity_Date < '2013-05-16'
    ORDER BY dbo.ZERORATES.Maturity_Date DESC)
UNION
(SELECT TOP 1 dbo.ZERORATES.Maturity_Date AS Date2, dbo.ZERORATES.Zero_Rate AS Rate2
    FROM dbo.ZERORATES
    WHERE dbo.ZERORATES.Maturity_Date > '2013-05-16'
    ORDER BY dbo.ZERORATES.Maturity_Date ASC)

person Michael    schedule 16.05.2011    source источник
comment
Вам нужно первое и последнее значение даты погашения, вы можете использовать функции MIN и MAX для получения этих значений.   -  person maple_shaft    schedule 16.05.2011
comment
Тогда вы можете использовать OVER() и PARTITION BY.   -  person ypercubeᵀᴹ    schedule 16.05.2011


Ответы (5)


Попробуйте встроить свои запросы в выборку

select * from
(SELECT TOP 1 dbo.ZERORATES.Maturity_Date AS Date1, dbo.ZERORATES.Zero_Rate AS Rate1
    FROM dbo.ZERORATES
    WHERE dbo.ZERORATES.Maturity_Date < '2013-05-16'
    ORDER BY dbo.ZERORATES.Maturity_Date DESC) as T
UNION
select * from
(SELECT TOP 1 dbo.ZERORATES.Maturity_Date AS Date2, dbo.ZERORATES.Zero_Rate AS Rate2
    FROM dbo.ZERORATES
    WHERE dbo.ZERORATES.Maturity_Date > '2013-05-16'
    ORDER BY dbo.ZERORATES.Maturity_Date ASC) as T
person Mikael Eriksson    schedule 16.05.2011
comment
Спасибо, Микаэль, это именно то, что мне нужно. - person Michael; 16.05.2011

ОБЪЕДИНЕНИЕ может иметь только один порядок, который должен быть только в последнем выборе, подзапрос может иметь только 1 столбец, измените его на ниже:

SELECT TOP 1 dbo.ZERORATES.Maturity_Date AS Date1, dbo.ZERORATES.Zero_Rate AS Rate1
    INTO #Temp1
FROM dbo.ZERORATES    
WHERE dbo.ZERORATES.Maturity_Date < '2013-05-16'  
ORDER BY dbo.ZERORATES.Maturity_Date DESC
UNION
SELECT TOP 1 dbo.ZERORATES.Maturity_Date AS Date1, dbo.ZERORATES.Zero_Rate AS Rate1
    INTO #Temp2    
FROM dbo.ZERORATES    
WHERE dbo.ZERORATES.Maturity_Date > '2013-05-16'    
ORDER BY dbo.ZERORATES.Maturity_Date ASC

SELECT * FROM #Temp1
UNION 
SELECT * FROM #Temp2
person TBohnen.jnr    schedule 16.05.2011
comment
Это не делает то, что я хочу. Мне нужны 2 дня, ближайшие к указанному там. Этот оператор дает первую дату в таблице и первую дату больше указанной. - person Michael; 16.05.2011
comment
@Michael: Если вам нужны 2 дня, ближайшие к указанному там, то ваш исходный запрос неверен. - person ypercubeᵀᴹ; 16.05.2011
comment
Если вы хотите ближайший сверху и ближайший снизу, тогда ОК. - person ypercubeᵀᴹ; 16.05.2011
comment
Да, ближайший сверху и ближайший снизу - person Michael; 16.05.2011
comment
Хм, странно, я проверил этот запрос, и он даст вам шкаф сверху и ближайший снизу? - person TBohnen.jnr; 16.05.2011

ORDER BY недействителен в представлениях EDIT (ТОЛЬКО в SQLServer)если не указан SELECT TOP /EDIT. Попробуйте упорядочить набор результатов после присоединения к своим таблицам.

person maple_shaft    schedule 16.05.2011

UNION может иметь только один ORDER, чтобы получить верхнее и нижнее значения, вы можете использовать MIN и MAX

SELECT MAX(dbo.ZERORATES.Maturity_Date) AS Date, dbo.ZERORATES.Zero_Rate AS Rate
FROM dbo.ZERORATES
WHERE dbo.ZERORATES.Maturity_Date < '2013-05-16'
GROUP BY dbo.ZERORATES.Zero_Rate

UNION

SELECT MIN(dbo.ZERORATES.Maturity_Date) AS Date, dbo.ZERORATES.Zero_Rate AS Rate
FROM dbo.ZERORATES
WHERE dbo.ZERORATES.Maturity_Date > '2013-05-16'
GROUP BY dbo.ZERORATES.Zero_Rate
person Justin Wignall    schedule 16.05.2011
comment
Просто мысль выше не будет работать с несколькими нулевыми ставками, хотя может помочь вам найти ответ. Может быть ТОП 1 вдобавок к этому... - person Justin Wignall; 16.05.2011

Если для каждой даты не более 1 строки, это будет сделано:

SELECT z.Maturity_Date AS Date
     , z.Zero_Rate AS Rate
FROM
    dbo.ZERORATES z
        JOIN 
        (   SELECT MAX(dbo.ZERORATES.Maturity_Date) AS D
            FROM dbo.ZERORATES
            WHERE dbo.ZERORATES.Maturity_Date < '2013-05-16'
        UNION  
            SELECT MIN(dbo.ZERORATES.Maturity_Date) AS D
            FROM dbo.ZERORATES
            WHERE dbo.ZERORATES.Maturity_Date > '2013-05-16'
        )
    AS maxmin
        ON z.Maturity_Date = maxmin.D

Я уверен, что есть более элегантное решение с использованием OVER() и PARTITION BY, но сейчас я не рядом с SQL-сервером, чтобы проверить.

person ypercubeᵀᴹ    schedule 16.05.2011