SQL für Bestellungen nach Warenwert

Thema wurde von sirtet, 1. September 2023 erstellt.

  1. sirtet

    sirtet Erfahrener Benutzer

    Registriert seit:
    4. Juli 2012
    Beiträge:
    1.122
    Danke erhalten:
    88
    Danke vergeben:
    89
    Hat ev. jemand eine Abfrage zur Hand oder einen Hinweis wie vorgehen?
    Ich möchte zb. alle Bestellungen des aktuellen Jahres, sortiert nach Warenwert.

    Hab eine Weile rumgesucht und Dinge probiert, aber den Warenwert nirgends gefunden...
    Anfangs dachte ich, ich brauche orders_total.value, aber da sind zb. Gutscheine schon abgezogen...

    SELECT
    ot.value
    ,o.date_purchased
    , o.*
    FROM
    orders_total ot
    JOIN
    orders o ON o.orders_id = ot.orders_id
    WHERE
    ot.class = 'ot_total'
    AND o.date_purchased > '2022-12-31'
    AND o.customers_name <> 'Shop Admin' -- Testbestellungen ausschliessen
    AND o.orders_status = 3 -- Status 3=Versendet
    ORDER BY
    ot.value ASC

    Ich vermute, Warenwert ist nicht gespeichert, sondern wird immer gerechnet aus den Positionen?
     
  2. Christian Mueller

    Christian Mueller Beta-Held

    Registriert seit:
    4. Juli 2011
    Beiträge:
    3.780
    Danke erhalten:
    942
    Danke vergeben:
    303
    Der Warenwert sollte ot_subtotal sein.
     
  3. sirtet

    sirtet Erfahrener Benutzer

    Registriert seit:
    4. Juli 2012
    Beiträge:
    1.122
    Danke erhalten:
    88
    Danke vergeben:
    89
    Danke, zu einfach...
     
  4. sirtet

    sirtet Erfahrener Benutzer

    Registriert seit:
    4. Juli 2012
    Beiträge:
    1.122
    Danke erhalten:
    88
    Danke vergeben:
    89
    Bekomme mit untenstehendem SQL so eine Ausgabe:

    Code:
    +-------------+------------------+-------------------+
    | Bestellwert | anz_Bestellungen | Bestellwert_Summe |
    | ---         | ---              | ---               |
    | 2020        |                  |                   |
    | ___         | ___              | ___               |
    | 4.00        | 1                | 4.00              |
    | 5.00        | 1                | 5.00              |
    | 6.00        | 2                | 12.00             |
    | 6.30        | 2                | 12.60             |
    | ___         | ___              | ___               |
    | total       | 6                | 33.60             |
    +-------------+------------------+-------------------+
    Code:
    /* Bestellungen mit tiefem Bestellwert */
    SET @bestellwert = 25; -- finde Best. unter diesem Wert
    SET @jahr = 2020;
    SET @adminname = 'Shop Admin'; -- Testbestellungen von Admin ausschliessen
    
    DROP TEMPORARY TABLE IF EXISTS results;
    CREATE TEMPORARY TABLE results (Bestellwert DECIMAL(6,2), anz_Bestellungen INT, Bestellwert_Summe DECIMAL(6,2)  );
    DROP TEMPORARY TABLE IF EXISTS output;
    CREATE TEMPORARY TABLE output (Bestellwert VARCHAR(10), anz_Bestellungen VARCHAR(10), Bestellwert_Summe VARCHAR(10) );
    
    INSERT INTO results (
       SELECT
          ot.value AS Bestellwert,
          COUNT(ot.value) AS anz_Bestellungen,
          COUNT(ot.value) * ot.value AS Bestellwert_Summe
        FROM
          orders_total ot
        JOIN
          orders o ON o.orders_id = ot.orders_id
        WHERE
          ot.class = 'ot_subtotal'  -- enthält Bestellwert
          AND YEAR (o.date_purchased) = @jahr
          AND o.customers_name <> @adminname
          AND o.orders_status = 3 -- Status 3 = Versendet
          AND ot.value < @bestellwert
        GROUP BY
          ot.value
        ORDER BY
          ot.value ASC
    );
    INSERT INTO output VALUES ( @jahr, '', '');
    INSERT INTO output VALUES ( '___', '___', '___');
    INSERT INTO output SELECT * FROM results;
    INSERT INTO output VALUES ( '___', '___', '___');
    INSERT INTO output SELECT  'total', SUM(`anz_Bestellungen`), SUM(`Bestellwert_Summe`) FROM results;
    
    SELECT * FROM output;

    Um meine potenziellen Porto-Kosten bei kleinen Bestellwerten besser zu verstehen, hab ich noch sowas gemacht:

    Code:
    +------+-------------------+------------------+--------------------+--------------------+---------+
    | Jahr | Bestellwert_unter | Anz_Bestellungen | Bestellwerte_Summe | Summe_Porto @ 12.- | % Porto |
    | ---  | ---:              | ---:             | ---:               | ---:               | ---:    |
    | 2019 | 10.00             | 30               | 219.74             | 360.00             | 163.83  |
    | 2019 | 15.00             | 52               | 480.67             | 624.00             | 129.82  |
    
    Code:
    /* Anzahl Bestellungen gruppiert nach Bestellwert, Hypothetischer Anteil Porto-Kosten*/
    
    -- Clean up the temporary table
    DROP TEMPORARY TABLE IF EXISTS temp_results;
    -- Initialize variables
    SET @startjahr = 2019;
    SET @endjahr = 2022;
    SET @adminname = 'Shop Admin'; -- Testbestellungen von Admin ausschliessen
    SET @startwert = 10; -- niedrigster zu suchender Bestellwert
    SET @endwert = 50; -- max. zu suchender Bestellwert
    SET @step = 5; -- Bestellwerte werden @step €-Blöcke zusammengefasst
    SET @porto = 12; -- hypothetische effektiv-Kosten für den Versand
    SET @portorow = CONCAT('Summe_Porto @ ', @porto, '.-'); -- Name der Porto-Spalte
    
    -- Create a temporary table to store the results
    SET @str = CONCAT( 'CREATE TEMPORARY TABLE temp_results (Jahr varchar(4), Bestellwert_unter decimal(6,2), Anz_Bestellungen INT, Bestellwerte_Summe decimal(6,2), `',@portorow,'` decimal(6,2), `% Porto` decimal(6,2));');
    -- SELECT @str;
    prepare stmt from @str;
    execute stmt;
    deallocate prepare stmt;
    
    -- Loop through values
    drop procedure if exists myproc;
    DELIMITER //
    CREATE PROCEDURE myproc()
    BEGIN
    SET @jahr = @startjahr;
    WHILE @jahr <= @endjahr DO
    
    SET @start = @startwert;
    WHILE @start <= @endwert DO
      INSERT INTO temp_results
      SELECT
        @jahr AS Jahr,
         @start AS wert_value,
        SUM(`anz_bestell`) AS anz_bestell_sum,
        SUM(`zw_summe`) AS zw_summe_sum,
        SUM(`anz_bestell`) * @porto AS `porto`,
        100 / ( SUM(`zw_summe`) / ( SUM(`anz_bestell`) * @porto ) ) AS anteil_porto
      FROM (
        SELECT
          ' ',
          ot.value,
          COUNT(ot.value) AS anz_bestell,
          COUNT(ot.value) * ot.value AS zw_summe
        FROM
          orders_total ot
        JOIN
          orders o ON o.orders_id = ot.orders_id
        WHERE
          ot.class = 'ot_subtotal'  -- enthält Bestellwert
          AND YEAR(o.date_purchased) = @jahr
          AND o.customers_name <> @adminname
          AND o.orders_status = 3 -- Status 3 = Versendet
          AND ot.value < @start
        GROUP BY
          ot.value
        ORDER BY
          ot.value ASC
      ) bestell;
    
      -- Increment for the next iteration
      SET @start = @start + @step;
    END WHILE;
    SET @jahr = @jahr + 1;
    INSERT INTO temp_results VALUES ('____',NULL,NULL,NULL,NULL,NULL );
    END WHILE;
    END//
    DELIMITER ;
    CALL myproc();
    
    -- Select the results from the temporary table
    SELECT * FROM temp_results;
    -- Clean up the temporary table
    DROP TEMPORARY TABLE IF EXISTS temp_results;

    PS:
    Hmm, Tabellen einfügen können wäre noch cool, gibts da was das ich übersehe?
    Und SQL als Sprache für CODE Blöcke wäre auch cool...