2012-01-12 72 views
2

我有这个查询即将通过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也。

我将不胜感激任何帮助。

+0

你如何确定“最新”的是什么?桌子上有没有可以提供这些信息的字段? – malonso 2012-01-12 12:24:16

+0

是的。 b.'''(法案的日期)应该是最新的。你懂我的意思吗? – Vay 2012-01-12 14:43:04

回答

0

不知道是否适用于MySQL,但怎么样LIMIT 1

+0

这会很好,如果我只能限制一个特定的行像'b.date'。但是如果我在查询结尾处添加LIMIT,我会将所有给定的结果限制为1,而我需要其他结果。 – Vay 2012-01-12 12:25:15

+0

如何在where子句之前获取当前日期,如何在临时表中说出 - 然后可以限制结果? – ChrisBD 2012-01-12 12:34:09

+0

我添加了'ORDER BY MAX(b.date)DESC'来解决这个问题。但是谢谢你! – Vay 2012-01-12 12:37:47

1

是的,只要加入“LIMIT 1”结尾:看MySQL documentation for select

但请注意,您必须添加ORDER BY以确保您获得“最新”行,具体取决于您的意思 - bills.datecoupons.expires

+0

但是,这不会限制我获得其他可能的结果吗?我想用这个查询做一个while循环来获取特定合作伙伴('partners')的所有特定数据。 – Vay 2012-01-12 12:29:16

+0

对不起,你是对的,我误解了你的问题 - 这不是你想限制行,而是防止重复。当然,你仍然得到重复的优惠券行,但只是发生在列表进一步下降?如何使用子查询?我会模拟一个例子... – craigmj 2012-01-12 12:58:03

+0

这将是很好的你。我的问题是,现在我只会在查询结尾用'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

1

如果要使用最新结果(请参阅:http://www.w3schools.com/sql/sql_func_max.asp),请在bills.date行使用Max函数。

+0

工作正常!我已经把'ORDER BY MAX(b.date)DESC'放在最后。谢谢。 – Vay 2012-01-12 12:36:06

+0

那么,我现在的问题是,在查询结束时,我只会用'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

+0

在第一个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

1

这里的问题是billspartners有关,而不是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列表优惠券符合您的要求,那么就检索这些优惠券。

但是,玩它,我不确定您的要求是否有意义:您正在检索的优惠券或者有一个月前的有效日期,或者是与一个月结算的合作伙伴关联的优惠券前?在这种方法中,您只能获得优惠券清单,然后需要检索最新的帐单或合作伙伴详细信息,假设总是有关联的合作伙伴?在那儿?

希望有帮助,克雷格

+0

哇,我真的很感谢你的时间来帮助我!谢谢。我没有太多的子查询经验,应该告诉你我需要什么数据。我在这里写了*来简化它,但我真的需要选择'p.email','c.id'和'p.id'。所以我不需要'账单'的任何数据。我想给合作伙伴发送一封电子邮件,说明已经创建了一个新账单,并用c.id(coupon-id)和p.id(partner-id)在'bills'中插入一个新账单。你能给我任何进一步的建议如何解决这个问题吗?再次感谢! – Vay 2012-01-12 14:28:06

+0

每个优惠券是否有一个且只有一个合作伙伴? (很高兴!) – craigmj 2012-01-12 14:41:53

+0

是的,一张优惠券不可能有另一张。但是一个合作伙伴可以有多个优惠券。这个系统就像Groupon系统。 – Vay 2012-01-12 14:43:49