我看到在SQL中,GROUP BY必须在ORDER BY表达式之前。这是否意味着在分组丢弃相同的行/列之后就完成了排序?
因为我似乎需要首先按时间戳记列A对行进行排序,然后才丢弃列A中具有相同值的行。不知道如何完成此操作…
我正在使用MySQL 5.1.41
create table ( A int, B timestamp )
数据可以是:
+-----+-----------------------+ | A | B | +-----+-----------------------+ | 1 | today | | 1 | yesterday | | 2 | yesterday | | 2 | tomorrow | +-----+-----------------------+
我想要的结果是:
+-----+-----------------------+ | A | B | +-----+-----------------------+ | 1 | today | | 2 | tomorrow | +-----+-----------------------+
基本上,我想要B列中具有最新时间戳的行(请考虑ORDER BY),而A列中的每个值仅需要一行(请考虑DISTINCT或GROUP BY)。
我的实际项目详细信息,如果您需要这些:
在现实生活中,我有两个表-users和payment_receipts。
users
payment_receipts
create table users ( phone_nr int(10) unsigned not null, primary key (phone_nr) ) create table payment_receipts ( phone_nr int(10) unsigned not null, payed_ts timestamp default current_timestamp not null, payed_until_ts timestamp not null, primary key (phone_nr, payed_ts, payed_until_ts) )
这些表可能包括其他列,在此我忽略了与IMO不相关的所有内容。作为移动支付方案的一部分,我必须定期通过移动蜂窝网络向用户发送SMS,具体取决于支付是否到期。付款是在发送SMS时实现的,需要缴纳附加税。我会保留所有通过以下方式完成的付款的记录:payment_receipts表格,用于记账,模拟一个真实的商店,买方和卖方均会获得购买收据的副本,以供参考。该表存储了我每张收据的(卖方)副本。客户收据就是收到的SMS本身。每次发送SMS(从而完成付款)时,都会在该表中插入一条收据记录,指明何时付款以及何时付款。为了解释后者,请想象一个订阅服务,但是它无限期地进行直到用户明确选择退出为止,此时用户记录将被删除。进行付款时,提前一个月,所以作为一项规则,不同的之间payed_ts和payed_until_ts30天的时间。
payed_ts
payed_until_ts
自然,我有一个每天执行的批处理作业,需要选择作为自动订阅续订的一部分应每月付款的用户列表。要将其链接到前面的虚拟示例,电话号码列phone_nr是a和payed_until_ts是b,但是在实际代码中有两个表,这使我想到以下行为及其含义:删除用户记录时,收据仍保留,用于簿记。因此,不仅需要按日期对付款进行分组并丢弃所有付款,而且还需要丢弃最新的付款收据日期,而且还需要当心不要选择不再有匹配的用户记录的收据。
phone_nr
a
b
I am solving the problem of selecting records that are due payment by finding the receipts with the latest payed_until_ts value (as in most cases there will be several receipts for each phone number) for each phone_nr and out of those rows I further need to leave only those phone_numbers where the payed_until_ts is earlier than the time the batch job executes. I loop over the list of these numbers and send out payments, storing a new receipt for each sent SMS, where payed_ts is now() and payed_until_ts is now() + interval 30 days.
now()
now() + interval 30 days
Select a,b from (select a,b from table order by b) as c group by a;