2016-07-01 17 views
0

In der ersten Tabelle habe ich Bestellungen. In der zweiten - Nachrichten, die an diese Aufträge senden. Ich muss Datum und Status von der letzten Nachricht erhalten (oder NULL, wenn Nachrichten noch nicht gesendet haben) für jeden Auftrag, der aktiv = 1 ist. Die Tabellen, die mit dem zusammengesetzten Schlüssel verbunden sind - "order_id + offer".Holen Sie sich das letzte Element in jeder Gruppe MySql

"orders" -Tabelle:

+----------+----------+--------+----------+ 
| order_id | offer | active | timezone | 
+----------+----------+--------+----------+ 
|  6 | kopiya |  1 |  0 | 
|  6 | kopiya-3 |  1 |  0 | 
|  10 | kopiya |  1 |  180 | 
|  23 | kopiya-2 |  1 |  0 | 
|  27 | kopiya-2 |  0 |  0 | 
+----------+----------+--------+----------+ 

"sms" Tabelle:

+------+----------+----------+------+--------+---------------------+ 
| key_ | order_id | offer | type | status | date    | 
+------+----------+----------+------+--------+---------------------+ 
| 1 |  6 | kopiya | text |  1 | 2016-06-20 00:00:00 | 
| 2 |  6 | kopiya-3 | text |  0 | 2016-06-21 00:00:00 | 
| 3 |  10 | kopiya | text |  0 | 2016-06-27 00:00:00 | 
| 4 |  27 | kopiya-2 | text |  1 | 2016-06-21 00:00:00 | 
| 6 |  6 | kopiya-3 | text |  1 | 2016-06-23 00:00:00 | 
+------+----------+----------+------+--------+---------------------+ 

Das Ergebnis wird sein:

+----------+----------+---------------------+--------+ 
| order_id | offer | last_date   | status | 
+----------+----------+---------------------+--------+ 
|  6 | kopiya | 2016-06-20 00:00:00 |  1 | 
|  6 | kopiya-3 | 2016-06-23 00:00:00 |  1 | 
|  10 | kopiya | 2016-06-27 00:00:00 |  0 | 
|  23 | kopiya-2 | NULL    | NULL | 
+----------+----------+---------------------+--------+ 

Diese Abfrage funktioniert nicht richtig:

SELECT o.order_id, o.offer, max(date) as last_date, status 
FROM orders AS o 
LEFT JOIN sms AS s 
ON o.order_id=s.order_id AND o.offer=s.offer 
WHERE `active` = 1 
GROUP BY o.order_id, o.offer; 

Es zeigt:

+----------+----------+---------------------+--------+ 
| order_id | offer | last_date   | status | 
+----------+----------+---------------------+--------+ 
|  6 | kopiya | 2016-06-20 00:00:00 |  1 | 
|  6 | kopiya-3 | 2016-06-23 00:00:00 |  0 | 
|  10 | kopiya | 2016-06-27 00:00:00 |  0 | 
|  23 | kopiya-2 | NULL    | NULL | 
+----------+----------+---------------------+--------+ 

Für Taste „6 kopiya-3“ es Status zurückgeben = 0, aber 1 erwartet, weil er diesen Wert aus der ersten Reihe bekommen, anstatt mit max Datum rudern. Wie kann ich das beheben?

Antwort

0
SELECT o.order_id, o.offer, max(date) as last_date, (select (SELECT sd.status FROM sms sd WHERE sd.order_id=o.order_id AND sd.offer=s.offer ORDER BY sd.key_ DESC LIMIT 1) as 'st' case when st = '1' then '1' else '0' end) as status 
FROM orders AS o 
LEFT JOIN sms AS s 
ON o.order_id=s.order_id AND o.offer=s.offer 
WHERE `active` = 1 
GROUP BY o.order_id, o.offer; 

die funktionieren könnte, wenn meine Syntax

side note korrekt ist: meine Antwort ist schrecklich lol

1

Ist das nur das gleiche wie Unix Eine Antwort, nur anders formatiert? Wenn ja, dann schlagen sie mich dazu - aber beachten Sie, dass dies ein PK unter (order_id,offer) annimmt, und gibt eine etwas andere Ergebnismenge als angefordert zurück.

SELECT o.order_id 
    , o.offer 
    , s.date last_date 
    , s.status 
    FROM orders o 
    LEFT 
    JOIN 
    (SELECT x.* 
     FROM sms x 
     JOIN 
      (SELECT order_id 
        , offer 
        , MAX(date) date 
       FROM sms 
       GROUP 
        BY order_id 
        , offer 
      ) y 
      ON y.order_id = x.order_id 
      AND y.offer = x.offer 
      AND y.date = x.date 
    ) s 
    ON s.order_id = o.order_id 
    AND s.offer = o.offer 
    WHERE o.active = 1; 
+0

Nein, es scheint, dass Sie mich um ein paar Minuten zu schlagen. Ein Hinweis zu dieser Frage: Wenn Sie 'y' an' order_id', 'offer' und' date' anfügen, ist eine Zeile nicht garantiert. Es könnte theoretisch> 1 Zeilen mit den gleichen Werten geben diese Felder, in diesem Fall werden Sie mit Duplikaten enden. Wenn Sie 'MAX (date)' verwenden möchten, benötigen Sie wahrscheinlich noch eine weitere Unterauswahl, um das 'MAX (key_)' zu erhalten (oder wie auch immer Sie die "letzte" Zeile identifizieren würden, die Sie zurückgeben möchten). –

+0

Ja. Ich nehme ein PK auf '(order_id, offer)' an. – Strawberry

+0

Entschuldigung, ich verstehe das nicht wirklich. – Strawberry

0
SELECT 
    o.order_id, 
    o.offer, 
    s3.`date` AS last_date, 
    s3.status 
FROM 
    orders o 
    LEFT JOIN 
    (SELECT 
     s1.order_id, 
     s1.offer 
    FROM 
     sms s1 
     JOIN 
     (SELECT 
      MAX(key_) AS key_ 
      FROM 
      sms 
      GROUP BY 
      order_id, 
      offer) s2 ON s1.key_ = s2.key_) s3 ON (o.order_id = s3.order_id AND o.offer = s3.offer) 
0

Bingo, das Problem, wo Sie die GROUP BY setzen ist:

SELECT o.order_id, o.offer, max(date) as last_date, status 
FROM orders AS o 
LEFT JOIN sms AS s 
ON o.order_id=s.order_id AND o.offer=s.offer 
WHERE `active` = 1 
GROUP BY o.order_id, o.offer; 

Daraus ergibt sich wie folgt zusammen:

WITH C AS (SELECT --columns 
FROM Orders AS A 
WHERE O.Active = 1 
GROUP BY O.Order_ID, O.Offer) 

SELECT --columns 
FROM C 
INNER JOIN sms AS S ON O.Order_ID = S.order_ID 
        AND O.Offer = S.Offer; 

von nicht deterministisch Da die Gruppe ist, Sie Bekomme den Fehler, den du hattest. Stattdessen versuchen etwas wie folgt aus:

SELECT B.ORDER_ID, A.OFFER, B.Status, B.DATE 
FROM Orders A 
INNER JOIN (SELECT Order_ID, Offer, MAX([DATE]) AS [DATE], MAX(Status) AS [Status] 
      FROM #EXAMPLE2 
      GROUP BY Order_ID, OFFER) B ON A.Offer = B.OFFER 
            AND A.Order_ID = B.Order_ID 
WHERE ACTIVE = 1; 

Results: 
-- 6 kopiya  1  2016-06-20 00:00:00.000 
-- 27 kopiya-2 1  2016-06-21 00:00:00.000 
-- 6 kopiya-3 1  2016-06-23 00:00:00.000 
-- 23 kopiya-2 NULL NULL 

nun das Prädikat auf Ihrer Tabelle Orders tut, was es tun soll, und filtert die Ergebnisse.

+0

oops, lese das falsch (nur mit der Hälfte der Ergebnisse gearbeitet. XD) –

0

Ich denke, das tut, was Sie wollen:

select sms.* 
from orders o left join 
    sms 
    on o.order_id = sms.order_id and o.offer = sms.offer 
where sms.date = (select max(sms2.date) 
        from sms sms2 
        where sms2.order_id = sms.order_id and sms2.offer = sms.offer 
       ) or 
     sms.order_id is null 

Für diese Abfrage würde ich einen Index für sms(order_id, offer, date) beraten.

Verwandte Themen