2016-04-29 4 views
1

Я использую команду Crystal Reports 13 Add Command для выбора записей из базы данных Oracle, подключенной через Oracle 11g Client. Ошибка я получаю это ORA-00933: команда SQL не правильно закончилась, но я ничего не могу найти дело с моим кодом (неполное):SQL Command не правильно завершен - Oracle Subquery

/* Determine units with billing code effective dates in the previous month */ 
SELECT "UNITS"."UnitNumber", "BILL"."EFF_DT" 
FROM "MFIVE"."BILL_UNIT_ACCT" "BILL" 
LEFT OUTER JOIN "MFIVE"."VIEW_ALL_UNITS" "UNITS" ON "BILL"."UNIT_ID" = "UNITS"."UNITID" 
WHERE "UNITS"."OwnerDepartment" LIKE '580' AND TO_CHAR("BILL"."EFF_DT", 'MMYYYY') = TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -1), 'MMYYYY') 

INNER JOIN 

/* Loop through previously identified units and determine last billing code change prior to preious month */ 
(
SELECT "BILL2"."UNIT_ID", MAX("BILL2"."EFF_DT") 
FROM "MFIVE"."BILL_UNIT_ACCT" "BILL2" 
WHERE TO_CHAR("BILL2"."EFF_DT", 'MMYYYY') < TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -1), 'MMYYYY') 
GROUP BY "BILL2"."UNIT_ID" 
) 

ON "BILL"."UNIT_ID" = "BILL2"."UNIT_ID" 
ORDER BY "UNITS"."UnitNumber", "BILL"."EFF_DT" DESC 

Мы являемся государственным объектом, который арендует транспортные средства (единица) другим учреждениям. Каждый блок имеет код фактуры с соответствующей датой вступления в силу. Приложение должно разработать отчет единиц с изменениями кодов биллинга в предыдущем месяце.

Усложнение вопроса заключается в том, что для каждого элемента выше отчет должен также показывать последний код фактуры и соответствующую дату вступления в силу до предыдущего месяца. Краткий пример:

Учитывая эти данные и при условии его сейчас апрель 2016 (заказывается для ясности) ...

Unit Billing Code Effective Date Excluded 
---- ------------ -------------- -------- 
1  A    04/15/2016  Present month 
1  B    03/29/2016 
1  A    03/15/2016 
1  C    03/02/2016 
1  B    01/01/2015 
2  C    03/25/2016 
2  A    03/04/2016 
2  B    07/24/2014 
2  A    01/01/2014  A later effective date prior to previous month exists 
3  D    11/28/2014  No billing code change during previous month 

Отчет должен возвращать следующие ...

Unit Billing Code Effective Date 
---- ------------ -------------- 
1  B    03/29/2016 
1  A    03/15/2016 
1  C    03/02/2016 
1  B    01/01/2015 
2  C    03/25/2016 
2  A    03/04/2016 
2  B    07/24/2014 

Любой помощь в разрешении ошибки будет оценена.

+0

Предложение 'JOIN' не может следовать после предложения' WHERE' – Husqvik

ответ

0

Если where до Join действительно имеет значение для вас, используйте CTE. (Использование with пункт для временной таблицы и соединения на то же самое.)

With c as (SELECT "UNITS"."UnitNumber", "BILL"."EFF_DT","BILL"."UNIT_ID" -- Correction: Was " BILL"."UNIT_ID" (spacetanker) 
    FROM "MFIVE"."BILL_UNIT_ACCT" "BILL" -- Returning unit id column too, to be used in join 

LEFT OUTER JOIN "MFIVE"."VIEW_ALL_UNITS" "UNITS" ON "BILL"."UNIT_ID" = "UNITS"."UNITID" 
    WHERE "UNITS"."OwnerDepartment" LIKE '580' AND TO_CHAR("BILL"."EFF_DT", 'MMYYYY') = TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -1), 'MMYYYY')) 

    select * from c  --Filter out your required columns from c and d alias results, e.g c.UNIT_ID 
    INNER JOIN 

    --Loop through previously identified units and determine last billing code change prior to preious month */ 
    (
    SELECT "BILL2"."UNIT_ID", MAX("BILL2"."EFF_DT") 
    FROM "MFIVE"."BILL_UNIT_ACCT" "BILL2" 
    WHERE TO_CHAR("BILL2"."EFF_DT", 'MMYYYY') < TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -1), 'MMYYYY') 
    GROUP BY "BILL2"."UNIT_ID" 
    ) d 

    ON c."UNIT_ID" = d."UNIT_ID" 
    order by c."UnitNumber", c."EFF_DT" desc -- COrrection: Removed semicolon that Crystal Reports didn't like (spacetanker) 

Кажется, этот запрос имеет много возможности для настройки, хотя. Тем не менее, тот, кто имеет доступ к данным и спецификации требований, является лучшим судьей.

EDIT: Вы не в состоянии видеть данные ПРИОР к предыдущему месяцу, так как вы используете BILL.EFF_DT в заявлении выберите свой вопрос, который фильтруется, чтобы дать только даты предыдущего месяца (..AND TO_CHAR("BILL"."EFF_DT", 'MMYYYY') = TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -1), 'MMYYYY'))

Если вы хотите, чтобы данные были такими, как вы хотите, я думаю, вам нужно использовать раздел BILL2 (часть d в моем подзапросе), указав псевдоним Max (EFF_DT) и используя этот псевдоним в вашем предложении select.

+0

@ IaB, спасибо. Ваши предложения, похоже, включают в себя логику, однако CR возвращает ужасную команду SQL, которая неправильно закончила ошибку, когда я пытаюсь ее выполнить. Теперь посмотрим на это подробно. – spacetanker

+0

@spacetanker, я потерял счет bill.unit_id в c. Ред. –

+0

@IaB. К сожалению, все равно получено сообщение об ошибке. – spacetanker

1

У вас есть статья WHERE до пункта INNER JOIN. Это недопустимый синтаксис - если поменять их местами, он должен работать:

SELECT "UNITS"."UnitNumber", 
     "BILL"."EFF_DT" 
FROM "MFIVE"."BILL_UNIT_ACCT" "BILL" 
     LEFT OUTER JOIN 
     "MFIVE"."VIEW_ALL_UNITS" "UNITS" 
     ON "BILL"."UNIT_ID" = "UNITS"."UNITID" 

INNER JOIN 

/* Loop through previously identified units and determine last billing code change prior to preious month */ 
    (
    SELECT "UNIT_ID", 
      MAX("EFF_DT") 
    FROM "MFIVE"."BILL_UNIT_ACCT" 
    WHERE TO_CHAR("EFF_DT", 'MMYYYY') < TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -1), 'MMYYYY') 
    GROUP BY "UNIT_ID" 
    ) "BILL2" 

    ON "BILL"."UNIT_ID" = "BILL2"."UNIT_ID" 
WHERE "UNITS"."OwnerDepartment" LIKE '580' 
AND TO_CHAR("BILL"."EFF_DT", 'MMYYYY') = TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -1), 'MMYYYY') 
ORDER BY "UNITS"."UnitNumber", "BILL"."EFF_DT" DESC 

Кроме того, вам нужно переместить "BILL2" псевдоним вне () скобки, поскольку вам не нужно псевдоним внутри скобок, но вы снаружи.

Вы действительно уверены, что вам нужны двойные кавычки ""? Двойные кавычки применяют чувствительность к регистру в именах столбцов - поведение по умолчанию для Oracle заключается в преобразовании всех имен таблиц и столбцов в верхний регистр для абстрагирования чувствительности к регистру от пользователя - поскольку вы используете как двойные кавычки, так и имена верхнего регистра, цитаты кажутся излишними.

+0

@MTD Спасибо. Я понял, что проблема синтаксиса смотрела мне в лицо. Несомненно, что я построил запрос, но результирующие записи показывают только изменения за предыдущий месяц. Перемещение предложения WHERE до конца ограничивает вывод, чтобы исключить последнюю эффективную дату до предыдущего месяца. – spacetanker

1

РЕШЕНИЕ :

SELECT DISTINCT "BILL2".* 
FROM "MFIVE"."BILL_UNIT_ACCT" "BILL" 
LEFT JOIN 

    /* Returns all rows for each unit with effective date >= maximum prior effective date and effective date < current month */ 
    (
    SELECT "UNITS"."UnitNumber" AS "UNITNO", 
    UPPER("UNITS"."SpecNoDescription") AS "TS_DESCR", 
    "UNITS"."UsingDepartment" AS "USING_DEPT", 
    "UNITS"."OwnerDepartment" AS "OWNING_DEPT", 
    "BILL"."BILLING_CODE", 
    "BILL"."EFF_DT", 
    "BILL"."UNIT_ID" 
    FROM "MFIVE"."BILL_UNIT_ACCT" "BILL" 
    LEFT OUTER JOIN "MFIVE"."VIEW_ALL_UNITS" "UNITS" ON "BILL"."UNIT_ID" = "UNITS"."UNITID" 
    WHERE TO_NUMBER(TO_CHAR(TRUNC("BILL"."EFF_DT"), 'YYYYMM'), '999999') < TO_NUMBER(TO_CHAR(TRUNC(ADD_MONTHS(SYSDATE, 0)), 'YYYYMM'), '999999') AND 
"UNITS"."OwnerDepartment" = '580' AND 
"BILL"."EFF_DT" >= 

    /* Returns maximum effective date prior to previous month for each unit */ 
    (
    SELECT MAX("BILL3"."EFF_DT") 
    FROM "MFIVE"."BILL_UNIT_ACCT" "BILL3" 
    WHERE "BILL3"."UNIT_ID" = "BILL"."UNIT_ID" AND 
     TO_NUMBER(TO_CHAR(TRUNC("BILL3"."EFF_DT"), 'YYYYMM'), '999999') < TO_NUMBER(TO_CHAR(TRUNC(ADD_MONTHS(SYSDATE, -1)), 'YYYYMM'), '999999') 
    GROUP BY "BILL3"."UNIT_ID" 
    ) 

) BILL2 

ON "BILL"."UNIT_ID" = "BILL2"."UNIT_ID" 
WHERE TO_CHAR("BILL"."EFF_DT", 'YYYYMM') = TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -1), 'YYYYMM') 
ORDER BY "BILL2"."UNITNO", "BILL2"."EFF_DT" DESC 
Смежные вопросы