在第一张表中,我有订单。在第二个 - 发送到这些订单的消息。对于每个有active = 1的订单,我需要从最后一条消息中获取日期和状态(如果消息尚未发送,则为NULL)。表格由复合键连接 - “order_id + offer”。
“订单”表:
+----------+----------+--------+----------+
| 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 |
+----------+----------+--------+----------+
“短信”表:
+------+----------+----------+------+--------+---------------------+
| 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 |
+------+----------+----------+------+--------+---------------------+
结果将是:
+----------+----------+---------------------+--------+
| 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 |
+----------+----------+---------------------+--------+
此查询无效:
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;
它显示:
+----------+----------+---------------------+--------+
| 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 |
+----------+----------+---------------------+--------+
对于键“6 kopiya-3”,它返回状态= 0但是预期为1,因为它从第一行获得此值而不是具有最大日期的行。我该如何解决这个问题?
答案 0 :(得分:1)
这与Unix One的答案是否相同,只是格式不同?
如果是这样,那么他们就会打败我 - 但请注意,这假设(order_id,offer)
上的PK,并返回与请求的结果略有不同的结果集。
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;
答案 1 :(得分: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;
如果我的语法正确可能会有效
旁注:我的答案很糟糕lol答案 2 :(得分: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)
答案 3 :(得分:0)
Bingo,问题出在GROUP BY
:
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;
这导致以下结果:
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;
由于group by不是确定性的,因此您会收到错误。 相反,尝试这样的事情:
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
现在,您的Orders表上的谓词会执行它应该执行的操作,并过滤结果。
答案 4 :(得分:0)
我认为这可以满足您的需求:
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
对于此查询,我建议sms(order_id, offer, date)
上的索引。