Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Prozentangabe

Dieses Thema im Forum "Oracle" wurde erstellt von Charly1979, 1 März 2014.

  1. Charly1979

    Charly1979 Benutzer

    Hallo an alle,

    bin neu in Forum und ist auch mein erstes Forum also habt bitte verständnis.
    Ich habe meine Abfrage soweit fertig mir fehlt aber noch der Prozentanteil und ich habe noch nichtmal einen Ansatz wie ich dieses Problem löse deshalb auch dieser Beitrag.

    Ich brauche zu der quantity noch den Prozentanteil, diesen auch gruppiert nach source_warehause.

    Also Bsp. BER3 xx% BMVD und yy% Hardline


    need_to_receive_by_datetimesource_warehouse_iddestination_warehouse_idsum(bas.quantity_requested)pg_category
    27-FEB-14BER3FRA11BMVD
    27-FEB-14BER3FRA12HARDLINE
    27-FEB-14CGN1FRA13BMVD
    27-FEB-14CGN1FRA12HARDLINE
    27-FEB-14DUS2FRA16BMVD
    27-FEB-14DUS2FRA18HARDLINE
    27-FEB-14EDE5FRA15BMVD
    27-FEB-14EDE5FRA15HARDLINE
    27-FEB-14FRA3FRA199BMVD
    27-FEB-14FRA3FRA122HARDLINE
    27-FEB-14LEJ1FRA111BMVD
    27-FEB-14LEJ1FRA12HARDLINE
    27-FEB-14MUC3FRA19BMVD
    27-FEB-14MUC3FRA17HARDLINE
    27-FEB-14ORY1FRA16BMVD
    27-FEB-14ORY1FRA13HARDLINE

    SQL Befehl lautet Momentan noch so:

    SELECT /*+ USE_HASH(bas, prg) */ bas.need_to_receive_by_datetime,
    bas.source_warehouse_id,
    bas.destination_warehouse_id,
    Sum(bas.quantity_requested),
    CASE
    WHEN prg.gl_product_group = 1
    OR prg.gl_product_group = 2
    OR prg.gl_product_group = 3
    OR prg.gl_product_group = 4
    OR prg.gl_product_group = 5
    OR prg.gl_product_group = 6
    OR prg.gl_product_group = 7
    OR prg.gl_product_group = 8 THEN
    'BMVD'
    ELSE 'HARDLINE'
    END AS PG_Category
    FROM xxx bas
    LEFT JOIN yyy prg
    ON bas.asin = prg.asin
    WHERE bas.need_to_receive_by_datetime >
    To_date('{RUN_DATE_YYYYMMDD}', 'YYYYMMDD')
    AND bas.need_to_receive_by_datetime <
    To_date('{RUN_DATE_YYYYMMDD}', 'YYYYMMDD')
    + 1
    AND bas.destination_warehouse_id = 'FRA1'
    AND prg.marketplace_id = 4
    GROUP BY bas.need_to_receive_by_datetime,
    bas.source_warehouse_id,
    bas.destination_warehouse_id,
    CASE
    WHEN prg.gl_product_group = 14
    OR prg.gl_product_group = 15
    OR prg.gl_product_group = 27
    OR prg.gl_product_group = 63
    OR prg.gl_product_group = 65
    OR prg.gl_product_group = 74
    OR prg.gl_product_group = 153
    OR prg.gl_product_group = 226 THEN 'BMVD'
    ELSE 'HARDLINE'
    END
    ORDER BY bas.source_warehouse_id ASC;


    Danke und Gruß


    Thomas
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Ja, kein Problem.

    Du aber bitte auch, daß ich (nicht nur um dieses Zeit) schlicht und ergreifend zu faul bin, anhand der unformatiert hingeworfenen Daten und SQL die Struktur der Tabelle zu erraten.

    Bitte:
    • nutze die Formatierungsmöglichkeiten im Forum, steht alles in der Hilfe
    • zeig anhand einen kurzen, sofort nachvollziehbaren Beispiel, was Du hast und was Du suchst.
     
  3. Charly1979

    Charly1979 Benutzer

    Hi,

    hoffe das passt jetzt so, wenn nicht gebe mir noch eine chance, bin lern fähig


    Diese Tabelle soll das Ziel sein bis auf die Spalte Prozent ist sie fertig
    Datum | von | an | Anzahl | PG Prozent
    27-FEB-14 | BER3 | FRA1 | 2199 | HARDLINE | 66%
    27-FEB-14 | BER3 | FRA1 | 1115 | BMVD |34%
    27-FEB-14 | CGN1 | FRA1 | 1405 | BMVD | 59%
    27-FEB-14 | CGN1 | FRA1 | 991 | HARDLINE | 41%

    Der Code wird jetzt hoffentlich formatiert angezeigt:


    Code:
    SELECT /*+ USE_HASH(bas, prg) */ bas.need_to_receive_by_datetime,
                                     bas.source_warehouse_id,
                                     bas.destination_warehouse_id,
                                     Sum(bas.quantity_requested),
                                     CASE
                                       WHEN prg.gl_product_group = 14
                                             OR prg.gl_product_group = 15
                                             OR prg.gl_product_group = 27
                                             OR prg.gl_product_group = 63
                                             OR prg.gl_product_group = 65
                                             OR prg.gl_product_group = 74
                                             OR prg.gl_product_group = 153
                                             OR prg.gl_product_group = 226 THEN
                                       'BMVD'
                                       ELSE 'HARDLINE'
                                     END AS PG_Category
    FROM   d_transfer_request_items bas
           LEFT JOIN d_mp_asins prg
                  ON bas.asin = prg.asin
    WHERE  bas.need_to_receive_by_datetime >
           To_date('{RUN_DATE_YYYYMMDD}', 'YYYYMMDD')
           AND bas.need_to_receive_by_datetime <
               To_date('{RUN_DATE_YYYYMMDD}', 'YYYYMMDD')
               + 1
           AND bas.destination_warehouse_id = 'FRA1'
           AND prg.marketplace_id = 4
    GROUP  BY bas.need_to_receive_by_datetime,
              bas.source_warehouse_id,
              bas.destination_warehouse_id,
              CASE
                WHEN prg.gl_product_group = 14
                      OR prg.gl_product_group = 15
                      OR prg.gl_product_group = 27
                      OR prg.gl_product_group = 63
                      OR prg.gl_product_group = 65
                      OR prg.gl_product_group = 74
                      OR prg.gl_product_group = 153
                      OR prg.gl_product_group = 226 THEN 'BMVD'
                ELSE 'HARDLINE'
              END
    ORDER  BY bas.source_warehouse_id ASC;
    
     
  4. akretschmer

    akretschmer Datenbank-Guru

    Du mußt halt die % berechnen, dazu die aktuelle Anzahl durch die Summe der Gruppe und das ganze mal 100.

    Code:
    test=*# select * from charly ;
     g | anzahl
    ---+--------
     1 |  2199
     1 |  1115
     2 |  1405
     2 |  991
    (4 rows)
    
    test=*# select g, anzahl, 100* (anzahl::numeric / sum(anzahl) over (partition by g))::numeric(5,2) from charly ;
     g | anzahl | ?column?
    ---+--------+----------
     1 |  2199 |  66.00
     1 |  1115 |  34.00
     2 |  1405 |  59.00
     2 |  991 |  41.00
    (4 rows)
    
    Das bekommst doch jetzt sicher noch eingebaut, oder?
     
  5. Charly1979

    Charly1979 Benutzer

    Tausend dank Teste es dann gleich mal "Partition by" war mir nicht bekannt cool danke. Werde mich melden wenn es klappt.
     
  6. akretschmer

    akretschmer Datenbank-Guru

    Ich verwende PostgreSQL, aber das sollte ähnlich zu Oraggle sein. Einer hat ja vom anderen abgeschrieben, ...
     
  7. Charly1979

    Charly1979 Benutzer

    Hi,

    bekomme die fehlermeldung.

    "Statement 1 is not valid. Missing IN or OUT parameter at index:: 1"

    kann nicht mit der meldung anfangen




    Code:
    SELECT /*+ USE_HASH(bas, prg) */ bas.need_to_receive_by_datetime,
                                     bas.source_warehouse_id,
                                     bas.destination_warehouse_id,
                                     Sum(bas.quantity_requested),
    
    100* (bas.quantity::numeric / sum(bas.quantity) over (partition by bas.source_warehouse_id))::numeric(5,2) as percent,
    
                                     CASE
                                       WHEN prg.gl_product_group = 14
                                             OR prg.gl_product_group = 15
                                             OR prg.gl_product_group = 27
                                             OR prg.gl_product_group = 63
                                             OR prg.gl_product_group = 65
                                             OR prg.gl_product_group = 74
                                             OR prg.gl_product_group = 153
                                             OR prg.gl_product_group = 226 THEN
                                       'BMVD'
                                       ELSE 'HARDLINE'
                                     END AS PG_Category
     
  8. akretschmer

    akretschmer Datenbank-Guru

    Ich kann hier auch nur wild raten, a) zeigst Du nicht alles, b) hab ich kein Oraggle. Kurze Suche via Goggle läßt mich aber vermuten, daß Du a) prepared Statements einsetzt und b) in diesen Parameter mit :bla übergeben werden und c) das hier sich dann mit den cast- Operator :: in die Quere kommt.

    Aber das ist nur eine ganz wilde Vermutung...
     
  9. Charly1979

    Charly1979 Benutzer

    Hi,
    lag anscheinend an dem numeric, habe diesen rausgenommen und das nächte Problem ist die Gruppierung am Ende wie gebe ich dieses ein?

    Statement 1 is not valid. ORA-00904: "PERCENT": invalid identifier: fehler meldung wenn ich nach dem "as" gruppiere

    Statement 1 is not valid. ORA-00934: group function is not allowed here: fehler Meldung wenn ich nach der Formel Gruppiere



    Code:
    SELECT /*+ USE_HASH(bas, prg) */ bas.need_to_receive_by_datetime,
                                     bas.source_warehouse_id,
                                     bas.destination_warehouse_id,
                                     Sum(bas.quantity_requested),
    
    100* (bas.quantity_requested / sum(bas.quantity_requested) over (partition by bas.source_warehouse_id)) as percent,
    
                                     CASE
                                       WHEN prg.gl_product_group = 14
                                             OR prg.gl_product_group = 15
                                             OR prg.gl_product_group = 27
                                             OR prg.gl_product_group = 63
                                             OR prg.gl_product_group = 65
                                             OR prg.gl_product_group = 74
                                             OR prg.gl_product_group = 153
                                             OR prg.gl_product_group = 226 THEN
                                       'BMVD'
                                       ELSE 'HARDLINE'
                                     END AS PG_Category
    FROM   d_transfer_request_items bas
           LEFT JOIN d_mp_asins prg
                  ON bas.asin = prg.asin
    WHERE  bas.need_to_receive_by_datetime >
           To_date('{RUN_DATE_YYYYMMDD}', 'YYYYMMDD')
           AND bas.need_to_receive_by_datetime <
               To_date('{RUN_DATE_YYYYMMDD}', 'YYYYMMDD')
               + 1
           AND bas.destination_warehouse_id = 'FRA1'
           AND prg.marketplace_id = 4
    GROUP  BY
    
                                     bas.source_warehouse_id,
                                     bas.destination_warehouse_id,
                                     percent,
                                     CASE
                                       WHEN prg.gl_product_group = 14
                                             OR prg.gl_product_group = 15
                                             OR prg.gl_product_group = 27
                                             OR prg.gl_product_group = 63
                                             OR prg.gl_product_group = 65
                                             OR prg.gl_product_group = 74
                                             OR prg.gl_product_group = 153
                                             OR prg.gl_product_group = 226 THEN
                                       'BMVD'
                                       ELSE 'HARDLINE'
                                     END
    
    
    ORDER BY  bas.source_warehouse_id ASC;    
     
  10. akretschmer

    akretschmer Datenbank-Guru

    Bist Du Dir sicher, daß Du das überhaupt danach gruppieren willst?

    In PG bekommst da einen deutlich besseren Fehlertext:

    Code:
    test=*# select column1, sum(column2) over (partition by column1) from foo group by 2;
    ERROR:  window functions are not allowed in GROUP BY at character 17
    STATEMENT:  select column1, sum(column2) over (partition by column1) from foo group by 2;
    ERROR:  window functions are not allowed in GROUP BY
    LINE 1: select column1, sum(column2) over (partition by column1) fro...
    
     
  11. Charly1979

    Charly1979 Benutzer

    Ohne Gruppierung bekömmlich die Fehlermeldung das ich es gruppieren muss.
    Es ist ätzend wenn man kurz vorm Ziel ist und man kommt nicht weiter
     
  12. akretschmer

    akretschmer Datenbank-Guru

    Ach so. Nun, das hätte ich eher für bas.need_to_receive_by_datetime erwartet.
     
  13. Charly1979

    Charly1979 Benutzer

    hihi stimmt hatte ich versehentlich rausgenommen kommt trotzdem noch not a GROUP BY expression

    Code:
    SELECT /*+ USE_HASH(bas, prg) */ bas.need_to_receive_by_datetime,
                                     bas.source_warehouse_id,
                                     bas.destination_warehouse_id,
                                     Sum(bas.quantity_requested),
                                     100* bas.quantity_requested / sum(bas.quantity_requested) over (partition by bas.source_warehouse_id)) as percent,
                                     CASE
                                       WHEN prg.gl_product_group = 14
                                             OR prg.gl_product_group = 15
                                             OR prg.gl_product_group = 27
                                             OR prg.gl_product_group = 63
                                             OR prg.gl_product_group = 65
                                             OR prg.gl_product_group = 74
                                             OR prg.gl_product_group = 153
                                             OR prg.gl_product_group = 226 THEN
                                       'BMVD'
                                       ELSE 'HARDLINE'
                                     END AS PG_Category
    FROM   d_transfer_request_items bas
           LEFT JOIN d_mp_asins prg
                  ON bas.asin = prg.asin
    WHERE  bas.need_to_receive_by_datetime >
           To_date('{RUN_DATE_YYYYMMDD}', 'YYYYMMDD')
           AND bas.need_to_receive_by_datetime <
               To_date('{RUN_DATE_YYYYMMDD}', 'YYYYMMDD')
               + 1
           AND bas.destination_warehouse_id = 'FRA1'
           AND prg.marketplace_id = 4
    GROUP  BY
                                     bas.need_to_receive_by_datetime,
                                     bas.source_warehouse_id,
                                     bas.destination_warehouse_id,
                                    
                                     CASE
                                       WHEN prg.gl_product_group = 14
                                             OR prg.gl_product_group = 15
                                             OR prg.gl_product_group = 27
                                             OR prg.gl_product_group = 63
                                             OR prg.gl_product_group = 65
                                             OR prg.gl_product_group = 74
                                             OR prg.gl_product_group = 153
                                             OR prg.gl_product_group = 226 THEN
                                       'BMVD'
                                       ELSE 'HARDLINE'
                                     END
    
    
    ORDER BY  bas.source_warehouse_id ASC;    
     
  14. akretschmer

    akretschmer Datenbank-Guru

    Nun nimmst noch das Case-Geschwür aus dem GROUP BY und ersetzt es mit PG_Category.
     
  15. Charly1979

    Charly1979 Benutzer

    so habe es zum laufen bekommen bin gespannt ob das result stimmt bas.quantity_requested hatte im group by gefehlt
     

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden