2016-04-30 6 views
0

Ich habe eine Order_transactions-Tabelle mit 3 relevanten Spalten. id (eindeutige ID für den Transaktionsversuch), order_id (die ID der Reihenfolge, für die der Versuch unternommen wird) und success ein int, das 0 ist, wenn fehlgeschlagen, und 1 wenn erfolgreich.MySQL - Finden von% der Aufträge mit einem Transaktionsfehler

Es kann 0 oder mehr fehlgeschlagene Transaktionen vor einer erfolgreichen Transaktion für jede order_id geben.

Die Frage ist, wie finde ich:

  • Die Anzahl der Aufträge, die nie
  • Die Anzahl der Aufträge eine erfolgreiche Transaktion hatte die mit einem Ausfall einer Transaktion hatte (schließlich erfolgreich oder nicht)
  • Die Anzahl der Aufträge, die nie
  • eine fehlgeschlagene Transaktion (Erfolg nur) hatte

ich weiß, das eine Kombination von verschiedenen, Gruppe ist durch, vielleicht ein subselect, etc, ich bin nur nicht genug in diesem genug versiert. Vielen Dank.

+0

möchten Sie order_id mit diesen Bedingungen oder Anzahl der Aufträge? – splash58

+0

Nur die Summe ist in Ordnung für diese Frage. (In der Zukunft möchte ich vielleicht die Aufträge überprüfen, die nie eine erfolgreiche Transaktion hatten.) – seth

Antwort

1

Um die Anzahl der Aufträge zu erhalten, die nie eine erfolgreiche Transaktion hatte können Sie:

Demo here

Die Anzahl der Aufträge, die eine Transaktion mit einem Fehler hatten (schließlich erfolgreich oder nicht) kann mit der Abfrage erhalten:

SELECT COUNT(*) 
FROM (
    SELECT order_id 
    FROM transactions 
    GROUP BY order_id 
    HAVING COUNT(CASE WHEN success = 0 THEN 1 END) > 0) AS t 

Demo here

Schließlich zu bekommen die Anzahl der Aufträge, die nie eine fehlgeschlagene Transaktion hatten (nur Erfolg):

SELECT COUNT(*) 
FROM (
    SELECT order_id 
    FROM transactions 
    GROUP BY order_id 
    HAVING COUNT(CASE WHEN success = 0 THEN 1 END) = 0) AS t 

Demo here

+0

Oooo. Vielen Dank! Das ist eine Technik, die mir nicht bewusst war. – seth

0

erfolgreiche Bestellung

select count(*) from 
(select distinct order_id from my_table where success = 1) as t; 

erfolglos um

select count(*) from 
(select distinct order_id from my_table where success = 0) as t; 

nie eingereicht Transaktion

select count(*) from 
(select distintc order_id from my_table where id not in 
     (select distinct order_id from my_table where success = 0)) as t; 
1

Sie wollen „zählt“ von Aufträgen, die bestimmte Bedingungen über mehrere Zeilen entsprechen, so würde ich mit einer GROUP BY order_id

SELECT ... 
    FROM mytable t 
GROUP BY t.order_id 

Um herauszufinden, starten, wenn eine bestimmte Reihenfolge je eine hatte fehlgeschlagene Transaktionen usw. Wir können Aggregate für Ausdrücke verwenden, die Bedingungen "testen".

Zum Beispiel:

SELECT MAX(t.success=1)   AS succeeded 
    , MAX(t.success=0)   AS failed 
    , IF(MAX(t.success=1),0,1) AS never_succeeded 
    FROM mytable t 
GROUP BY t.order_id 

Die Ausdrücke in der SELECT-Liste der Abfrage ist MySQL Stenografie. Wir könnten längere Ausdrücke (MySQL IF() - Funktion oder ANSI-CASE-Ausdrücke) verwenden, um ein äquivalentes Ergebnis, z.

Wir könnten die Spalte `order_id` in die SELECT-Liste zum Testen aufnehmen. Wir können die Ergebnisse für jede order_id mit den Zeilen in der ursprünglichen Tabelle vergleichen, um zu überprüfen, ob die zurückgegebenen Ergebnisse die Spezifikation erfüllen.

Um "Anzahl" von Aufträgen zu erhalten, können wir die Abfrage als Inline-Ansicht referenzieren und Aggregatausdrücke in der SELECT-Liste verwenden.

Zum Beispiel:

SELECT SUM(r.succeeded)    AS cnt_succeeded 
    , SUM(r.failed)     AS cnt_failed 
    , SUM(r.never_succeeded)  AS cnt_never_succeeded 
    FROM ( 
     SELECT MAX(t.success=1)   AS succeeded 
       , MAX(t.success=0)   AS failed 
       , IF(MAX(t.success=1),0,1) AS never_succeeded 
      FROM mytable t 
      GROUP BY t.order_id 
     ) r 

Da die Ausdrücke in der SELECT-Liste Rückkehr entweder 0, 1 oder NULL, können wir die SUM() Aggregat verwenden, um eine Zählung zu bekommen. Um ein COUNT() - Aggregat zu verwenden, müssten wir NULL anstelle eines 0 (FALSE) -Werts zurückgeben.

SELECT COUNT(IF(r.succeeded,1,NULL))  AS cnt_succeeded 
    , COUNT(IF(r.failed,1,NULL))   AS cnt_failed 
    , COUNT(IF(r.never_succeeded,1,NULL)) AS cnt_never_succeeded 
    FROM ( 
     SELECT MAX(t.success=1)   AS succeeded 
       , MAX(t.success=0)   AS failed 
       , IF(MAX(t.success=1),0,1) AS never_succeeded 
      FROM mytable t 
      GROUP BY t.order_id 
     ) r 

Wenn Sie eine Zählung aller order_id wollen, fügen Sie ein COUNT (1) Ausdruck in der äußeren Abfrage. Wenn Sie Prozentsätze benötigen, tun die Teilung und mit 100 multipliziert,

Zum Beispiel

SELECT SUM(r.succeeded)     AS cnt_succeeded 
    , SUM(r.failed)      AS cnt_failed 
    , SUM(r.never_succeeded)    AS cnt_never_succeeded 
    , SUM(1)        AS cnt_all_orders 
    , SUM(r.failed)/SUM(1)*100.0   AS pct_with_a_failure 
    , SUM(r.succeeded)/SUM(1)*100.0  AS pct_succeeded 
    , SUM(r.never_succeeded)/SUM(1)*100.0 AS pct_never_succeeded 
    FROM ( 
     SELECT MAX(t.success=1)   AS succeeded 
       , MAX(t.success=0)   AS failed 
       , IF(MAX(t.success=1),0,1) AS never_succeeded 
      FROM mytable t 
      GROUP BY t.order_id 
     ) r 

(Die Prozentsätze sind hier ein Vergleich zu der Anzahl der deutlichen order_id Werte, nicht als die Gesamtzahl der Zeilen in der Tabelle).

+0

Sprechen Sie über eine gründliche Antwort! Vielen Dank! – seth

Verwandte Themen