MySQL查询 - 只选择特定行的最新结果?
我有这个查询即将通过cronjob自动创建账单,如果过期的优惠券的日期恰好是1个月前或最后一个帐单日期(b.date
)恰好是一个月前。条件只能发生一次,因为具体的日期将在1个月前不会发生。MySQL查询 - 只选择特定行的最新结果?
SELECT *
FROM `coupons` AS c
LEFT JOIN `partners` AS p ON p.`id` = c.`pid`
LEFT JOIN `bills` AS b ON b.`pid` = c.`pid`
WHERE
(
CURRENT_DATE() = DATE_ADD(c.`expires`, INTERVAL 1 MONTH) // add something here?
OR
CURRENT_DATE() = DATE_ADD(b.`date`, INTERVAL 1 MONTH)
)
我的问题是,在第一个WHERE条件我得到了超过1个结果。所以我正在寻找一个解决方案,只选择最新的和唯一的一行b.date
也。
我将不胜感激任何帮助。
是的,只要加入“LIMIT 1”结尾:看MySQL documentation for select。
但请注意,您必须添加ORDER BY以确保您获得“最新”行,具体取决于您的意思 - bills.date
或coupons.expires
?
但是,这不会限制我获得其他可能的结果吗?我想用这个查询做一个while循环来获取特定合作伙伴('partners')的所有特定数据。 – Vay 2012-01-12 12:29:16
对不起,你是对的,我误解了你的问题 - 这不是你想限制行,而是防止重复。当然,你仍然得到重复的优惠券行,但只是发生在列表进一步下降?如何使用子查询?我会模拟一个例子... – craigmj 2012-01-12 12:58:03
这将是很好的你。我的问题是,现在我只会在查询结尾用'ORDER BY MAX(b.date)DESC'得到一个结果,但b.date不可能是正确的,因为它不是一个月前。我在b.date 2011-12-12和2010-12-12在'bills'中有两个测试行,他选择了2010年的一个...有点奇怪吗? – Vay 2012-01-12 13:03:38
如果要使用最新结果(请参阅:http://www.w3schools.com/sql/sql_func_max.asp),请在bills.date行使用Max函数。
工作正常!我已经把'ORDER BY MAX(b.date)DESC'放在最后。谢谢。 – Vay 2012-01-12 12:36:06
那么,我现在的问题是,在查询结束时,我只会用'ORDER BY MAX(b.date)DESC'得到一个结果,但是b.date不可能是正确的,因为它不是正确的一个月前。我在b.date 2011-12-12和2010-12-12在'bills'中有两个测试行,他选择了2010年的一个...有点奇怪吗? – Vay 2012-01-12 13:05:17
在第一个WHERE条件(CURRENT_DATE()= DATE_ADD(c.'expires',INTERVAL 1 MONTH)和(b.'''' =选择MAX(bill.'date')'from'bills' AS bill WHERE c.'pid' = bill.'pid')) – 2012-01-12 13:56:16
这里的问题是bills
与partners
有关,而不是coupons
。你的SQL,例如,是这样的:
drop table if exists coupons;
create table coupons (id int not null, pid int not null, expires date, primary key(id));
drop table if exists bills;
create table bills (id int not null, pid int not null, `date` date, primary key(id));
drop table if exists partners;
create table partners (id int, name varchar(20), primary key(id));
我们填充一些数据:
insert into partners values (1,'One');
insert into coupons values (1,1,'2011-12-12'), (2,1,'2011-11-11');
insert into bills values (1,1,'2011-12-12'), (2,1,'2011-11-11');
此时
select * from coupons c
left join partners p on c.pid = p.id
left join bills b on b.pid = c.pid
返回4行,这是有道理的:(合作伙伴1 ,coupon1,bill1),(p1,c1,b2),(p1,c2,b1),(p1,c2,b2)。如果再加上:
where
(
current_date() = date_add(c.expires, interval 1 month)
or
current_date() = date_add(b.`date`, interval 1 month)
)
我们得到3行:(P1,C1,B1),(P1,C1,B2),(P1,C2,B1)。为什么?因为coupon2或bill2在测试中都没有成功,而其他组合中至少有一个是成功的。
我怀疑你真正寻找的是更接近:
select *
from coupons c
where
c.id in
(select distinct c2.id from coupons c2
left join partners p2 on c2.pid=p2.id
left join bills b2 on b2.pid=c2.pid
where
current_date()=date_add(c2.expires, interval 1 month)
or
current_date()=date_add(b2.`date`, interval 1 month)
)
在这里我使用子查询来获得不同的优惠券ID列表优惠券符合您的要求,那么就检索这些优惠券。
但是,玩它,我不确定您的要求是否有意义:您正在检索的优惠券或者有一个月前的有效日期,或者是与一个月结算的合作伙伴关联的优惠券前?在这种方法中,您只能获得优惠券清单,然后需要检索最新的帐单或合作伙伴详细信息,假设总是有关联的合作伙伴?在那儿?
希望有帮助,克雷格
哇,我真的很感谢你的时间来帮助我!谢谢。我没有太多的子查询经验,应该告诉你我需要什么数据。我在这里写了*来简化它,但我真的需要选择'p.email','c.id'和'p.id'。所以我不需要'账单'的任何数据。我想给合作伙伴发送一封电子邮件,说明已经创建了一个新账单,并用c.id(coupon-id)和p.id(partner-id)在'bills'中插入一个新账单。你能给我任何进一步的建议如何解决这个问题吗?再次感谢! – Vay 2012-01-12 14:28:06
每个优惠券是否有一个且只有一个合作伙伴? (很高兴!) – craigmj 2012-01-12 14:41:53
是的,一张优惠券不可能有另一张。但是一个合作伙伴可以有多个优惠券。这个系统就像Groupon系统。 – Vay 2012-01-12 14:43:49
你如何确定“最新”的是什么?桌子上有没有可以提供这些信息的字段? – malonso 2012-01-12 12:24:16
是的。 b.'''(法案的日期)应该是最新的。你懂我的意思吗? – Vay 2012-01-12 14:43:04