2016-07-27 6 views
0

Ich versuche, eine T_SQL-Abfrage in eine Oracle-Abfrage zu konvertieren, um Informationen für ein Geschäftsjahr zu erhalten; was für mich von Oktober läuft von 1 bis 30 September Dies ist, was ich zu verwenden Ich versuche aber eine Fehlermeldung „ungültige SQL-Anweisung bin immer in Zeile 1Wie kann ich das Geschäftsjahr in meiner Oracle Select-Anweisung festlegen

var FromDate date 
IF extract(month from sysdate) BETWEEN 10 AND 12 
exec :FromDate := (extract(month from sysdate), 10, 1) ELSE 
exec :FromDate := (extract(year from sysdate)) - 1, 10, 1) 
         SELECT  COUNT(DISTINCT [CSMAST].[CM_CALL]) 
          FROM   [TIBURON].[CSMAST] [CSMAST] JOIN 
                [TIBURON].[SSCTAB] [SSCTAB] ON ([CSMAST].[CM_DID_1] = [SSCTAB].[RC_KEY]) 
          WHERE  [CSMAST].[CM_DATE] >= @FromDate AND [SSCTAB].[RC_TYPE] = 'O* 

Jede Hilfe sehr

+0

Ihre ‚IF‘ in Zeile 2 deplatziert ist - es ist nicht SQL und isn‘ t in einem PL/SQL-Kontext. Ihr Fehler kommt von Ihrem Kunden. Alle eckigen Klammern sind falsch, ebenso wie die @ -Syntax. Sie müssen vielleicht zurücktreten und darüber nachdenken, wie Oracle funktioniert. Und dann zeigen Sie zumindest Ihre Tabellendefinitionen, Beispieldaten und erwarteten Ergebnisse. –

Antwort

1

IF isn würde geschätzt Wenn Sie ein SQL-Konstrukt verwenden und es außerhalb eines PL/SQL-Blocks verwenden, sagt Ihnen der von Ihnen verwendete Client korrekt, dass er es nicht erkennt. Sie möchten wahrscheinlich nicht auf PL/SQL zurückgreifen, wie Sie es tun können, ohne das Startdatum als Bindevariable als separaten Schritt zu generieren

Wenn ich verstehe, was Sie versuchen, können Sie verwenden ein Fall Ausdruck in der Abfrage den Datumsbereich, so etwas wie entscheiden:

SELECT COUNT(DISTINCT CSMAST.CM_CALL) 
FROM TIBURON.CSMAST 
JOIN TIBURON.SSCTAB ON CSMAST.CM_DID_1 = SSCTAB.RC_KEY 
WHERE CSMAST.CM_DATE >= 
    CASE WHEN extract(month from sysdate) BETWEEN 10 AND 12 THEN 
    -- get start of current year, add 9 months to get this October 
    ADD_MONTHS(TRUNC(sysdate, 'YYYY'), 9) 
    ELSE 
    -- get start of current year, subtract 3 months to get previous October 
    ADD_MONTHS(TRUNC(sysdate, 'YYYY'), -3) 
    END 
AND SSCTAB.RC_TYPE = 'O*' 

nicht sicher, ob das letzte Zeile soll ein Platzhalter sein; wenn dies der Fall wäre es:

AND SSCTAB.RC_TYPE LIKE 'O%' 

Sie die Daten mit einem Dummy-Abfrage, dass Case-Ausdruck erzeugt sehen:

WITH t (dt) AS (
    SELECT add_months(SYSDATE, 6-LEVEL) FROM dual CONNECT BY LEVEL <= 27 
) 
SELECT dt, 
    CASE WHEN EXTRACT(MONTH FROM dt) BETWEEN 10 AND 12 THEN 
    -- get start of current year, add 9 months to get this October 
    ADD_MONTHS(TRUNC(dt, 'YYYY'), 9) 
    ELSE 
    -- get start of current year, subtract 3 months to get previous October 
    ADD_MONTHS(TRUNC(dt, 'YYYY'), -3) 
    END AS calculated 
FROM t 
ORDER BY dt; 

DT   CALCULATED 
---------- ---------- 
2014-10-27 2014-10-01 
2014-11-27 2014-10-01 
2014-12-27 2014-10-01 
2015-01-27 2014-10-01 
2015-02-27 2014-10-01 
2015-03-27 2014-10-01 
2015-04-27 2014-10-01 
2015-05-27 2014-10-01 
2015-06-27 2014-10-01 
2015-07-27 2014-10-01 
2015-08-27 2014-10-01 
2015-09-27 2014-10-01 
2015-10-27 2015-10-01 
2015-11-27 2015-10-01 
2015-12-27 2015-10-01 
2016-01-27 2015-10-01 
2016-02-27 2015-10-01 
2016-03-27 2015-10-01 
2016-04-27 2015-10-01 
2016-05-27 2015-10-01 
2016-06-27 2015-10-01 
2016-07-27 2015-10-01 
2016-08-27 2015-10-01 
2016-09-27 2015-10-01 
2016-10-27 2016-10-01 
2016-11-27 2016-10-01 
2016-12-27 2016-10-01 

Sie könnten sogar vereinfachen, dass so nur das Datum einmal gestutzt, und haben ein Einzel ADD_MONTHS() Anruf und legte den Fall Ausdruck innerhalb dass es die Nummer, die Sie addieren oder subtrahieren ist der einzige Teil, ändert:

WHERE CSMAST.CM_DATE >= ADD_MONTHS(TRUNC(sysdate, 'YYYY'), 
    CASE WHEN EXTRACT(MONTH FROM sysdate) BETWEEN 10 AND 12 THEN 9 ELSE -3 END) 
AND SSCTAB.RC_TYPE LIKE 'O%' 

, die den gleichen Effekt hat.

Schnell Demo frühere Termine zu zeigen, werden ignoriert, indem verspottet-up-Daten für zwei Tabellen:

with CSMAST(cm_date, cm_call, cm_did_1) as (
    select date '1999-12-31', 1, 1 from dual 
    union all select date '2014-09-30', 1, 2 from dual 
    union all select date '2015-10-01', 1, 3 from dual 
    union all select date '2015-12-31', 2, 4 from dual 
    union all select date '2016-01-01', 2, 5 from dual 
    union all select date '2016-09-30', 2, 6 from dual 
    union all select date '2016-10-01', 3, 7 from dual 
    union all select date '2016-12-31', 3, 8 from dual 
), 
SSCTAB (rc_key, rc_type) as (
    select level, 'O*' from dual connect by level < 10 
) 
SELECT * -- COUNT(DISTINCT CSMAST.CM_CALL) 
FROM CSMAST 
JOIN SSCTAB ON CSMAST.CM_DID_1 = SSCTAB.RC_KEY 
WHERE CSMAST.CM_DATE >= ADD_MONTHS(TRUNC(sysdate, 'YYYY'), 
    CASE WHEN EXTRACT(MONTH FROM sysdate) BETWEEN 10 AND 12 THEN 9 ELSE -3 END) 
AND SSCTAB.RC_TYPE LIKE 'O%'; 

CM_DATE  CM_CALL CM_DID_1  RC_KEY RC 
----------- ---------- ---------- ---------- -- 
2015-10-01   1   3   3 O* 
2015-12-31   2   4   4 O* 
2016-01-01   2   5   5 O* 
2016-09-30   2   6   6 O* 
2016-10-01   3   7   7 O* 
2016-12-31   3   8   8 O* 

6 rows selected 
+0

Sorry für keine Antwort wurde auf ein anderes Projekt gezogen. Ich habe Ihren Vorschlag ausprobiert, hatte aber zwei Probleme. Die Abfrage dauerte lange. Als es fertig war, hatte ich Aufzeichnungen beginnend mit dem Jahr 1999? – Perry

+0

Ich habe einige Tests gemacht und es scheint zu funktionieren OK; mit gespotteten Daten natürlich, aber ich habe einige von 1999 aufgenommen und es ignoriert alles vor 2015-10-01. Sind Sie sicher, dass diese Zeilen 1999 sind, nicht 2099, sagen Sie? Ist CM_DATE indiziert und tatsächlich ein Datum? Und um einige Merkwürdigkeiten auszuschließen, ist CSMAST eine Tabelle oder eine Ansicht? –

Verwandte Themen