#sql #oracle #oracle11g #database-migration
#sql #Oracle #oracle11g #база данных-миграция
Вопрос:
У меня есть запрос tsql в SQL Server, который работает нормально. Но когда я использую его внутри задачи execute sql в ssis для запуска с Oracle DB. Я получаю ошибки для «функция не разрешена в группе». Я знаю, что группировка Oracle отличается, но я недостаточно хорошо разбираюсь в этом, чтобы знать достаточно.
Как мне преобразовать этот запрос tsql в oracle — sql:
SELECT
TBL_A.EID AS MYID
, TBL_A.ID
, TBL_B.LOGIN AS LOGID
, TO_DATE(TBL_B.CM, 'MM/DD/YYYY') as MD
, sum(TBL_B.CS) as TTS
, sum(TBL_B.COTS) as HTS
, sum(TBL_B.CWS) as WTS
, sum(TBL_B.CL) as NTS
FROM
SRVR1.TBL1 TBL_A JOIN
SRVR2.TBL2 TBL_B
ON TBL_A.ID = TBL_B.LOGIN
GROUP BY
TBL_A.EID
,TBL_A.ID
,TBL_B.LOGIN
,TO_DATE(TBL_B.CM, 'MM/DD/YYYY') as MD
ORDER BY TBL_B.LOGIN,
TBL_B.CM ;
Комментарии:
1.
group by sum(..)
не имеет никакого смысла вообще. Ни в Oracle, ни в SQL Server. Что именно выDATEFROMPARTS
делаете? Иyear()
в Oracle нет никакой функции. Вы сами это написали? Каково намерениеrownum < 5
«там»? Это сработает не так, как вы думаете. И, пожалуйста, добавьте точное сообщение об ошибке к вашему вопросу.2. Независимо от того, какую СУБД вы используете, вы должны использовать объединения в стиле ANSI-92. Прошло более 25 лет с момента его появления. sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08 /…
3. Нет никаких шансов, что запрос работает так, как опубликовано в sql server. У вас есть агрегированные данные в group by, и у вас также есть столбцы с псевдонимами в group by. Рассматривали ли вы возможность преобразования в date вместо всех этих функций, чтобы превратить datetime в дату?
4. Также удалите псевдоним столбца (
as MD
) изGROUP BY
предложения.group by
Предложение не должно быть cut-n-pasteselect
предложения!5. Функции datefromparts можно упростить до этого. преобразовать(дата, getdate())
Ответ №1:
Я бы предложил начать с такого запроса:
SELECT TBL_A.EID AS MYID, TBL_A.ID AS LOGID
DATEFROMPARTS(year(TBL_B.CM), month(TBL_B.CM), day(TBL_B.CM)) as MD
sum(TBL_B.CS) as TTS,
sum(TBL_B.COTS) as HTS,
sum(TBL_B.CWS) as WTS,
sum(TBL_B.CL) as NUM
FROM SRVR1.TBL1 TBL_A JOIN
SRVR2.TBL2 TBL_B
ON TBL_A.ID = TBL_B.LOGIN
WHERE rownum < 5
GROUP BY TBL_A.EID, TBL_A.ID, TBL_B.LOGIN,
DATEFROMPARTS(year(TBL_B.CM),month(TBL_B.CM),day(TBL_B.CM))
ORDER BY TBL_B.LOGIN, TBL_B.CM ;
Примечания:
- Никогда не используйте запятые в
FROM
предложении. Всегда используйте явныйJOIN
синтаксис. - Не ставьте функции агрегирования, как
SUM()
вGROUP BY
. - Почему
id
иlogin
вSELECT
?JOIN
Условие указывает, что они одинаковы.
Кроме того:
datefromparts()
это функция только для SQL Serveryear()
,month()
, иday()
доступны только для SQL Serverrownum
только для Oracle- И
rownum
передGROUP BY
тем, как просто возвращает 5 произвольных строк, которые затем агрегируются.
Я не уверен, каким на самом деле должен быть ваш запрос. Это выглядело бы иначе в SQL Server по сравнению с Oracle.
Комментарии:
1. Я бы, по крайней мере, сделал оговорку, что
where
будет применен передgroup by
иorder by
, поэтому это не вернет «5 лучших совокупных строк», а займет 5 произвольных строк, сгруппирует их и упорядочит результаты. Это кажется маловероятным, чтобы быть правильным.2. Я просто добавил rownum в качестве замены top n в sql server. Это наполовину испеченный запрос, который я пытался преобразовать. Как мне создать версию datefromparts для oracle?
3. @DamonMatt … Что-то использует.
to_date()
4. Внес изменения для oracle и изменил исходное сообщение — по-прежнему появляется ошибка «команда sql не завершена должным образом».
5. @Gordon Linoff — Мне нужны первые два столбца в моем наборе данных.