我看到在SQL查询中,GROUP BY
必须在ORDER BY
表达式之前。这是否意味着在分组后进行排序会丢弃相同的行?
因为我似乎需要先按时间戳对行进行排序,* 然后 * 丢弃具有相同时间戳的行。
我用的是MySQL 5.1.41。
下面是用create table
表示的表的定义:
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
:
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)
)
这些表可能包括其他列,但我忽略了这些无关的。实施支付方案,我必须通过Hive网络向用户发送SMS,根据付款是否到期而定期间隔。当SMS发送时,付款被实现,因为接收者为此征税。我使用payment_receipts
表来记录所有已完成的付款,这是为了模拟一个真实的商店,买卖双方都得到一份购买收据的副本,以供参考。这个表存储了我的(卖方的)副本[每个收据]。客户的收据是收到的短信本身。每次发送短信(并且因此完成了支付)时,该表被插入收据记录,该收据记录陈述了谁支付、何时以及“直到何时”。为了解释后者,设想订阅服务,但是该订阅服务无限地跨越直到用户明确地选择退出,此时相应的用户记录被删除。付款提前一个月进行,因此作为规则,payed_ts
和payed_until_ts
之间的差异是30天的时间价值。
我有一个每天执行的批处理作业,需要选择一个按月付款的用户列表,作为上述自动订阅续订的一部分。为了将其链接到前面的虚拟示例,电话号码列phone_nr
将是列“A”,payed_until_ts
将是列“B”,但实际上有两个表,这与以下行为有关:删除用户记录时,必须保留收据以进行簿记。因此,我不仅需要按日期对付款进行分组并丢弃除最新付款收据日期以外的所有付款,还需要注意不要选择不再有匹配用户记录的收据。
为了解决选择所需记录(即到期付款的记录)的问题,我需要为每个phone_nr
查找具有最新payed_until_ts
时间戳的收据(可以有几个,显然),并且在这些记录中,我还需要仅选择payed_until_ts
早于批处理作业执行时间的那些电话号码。然后,我将向这些号码中的每一个发送SMS,为每个发送的SMS插入一个收据记录,其中payed_ts
是now()
,payed_until_ts
是now() + interval 30 days
。
但我似乎想不出所需的查询。
5条答案
按热度按时间gudnpqoy1#
bvjveswy2#
是的,首先进行分组,它会影响单个
select
,而排序会影响union
中所有select
语句的所有结果,例如:(使用
order by
中的字段号,因为我不想麻烦命名我的列)。每个group by
只影响它的select
,order by
影响组合的结果集。你所追求的似乎可以通过以下方式实现:
这使用
max
聚合函数来基本上完成预组排序(它不会在任何像样的DBMS中进行排序,而是简单地从合适的索引中选择最大值(如果可用))。xnifntxz3#
y0u0uwnf4#
根据您的新规则(PostgreSQL测试)
您想要查询:
原始答案(含更新):
留言内容:
1
返回两次,因为它们是多个b
值。这是可以接受的(建议)。您的数据应该永远不会有这个问题,因为c
是基于b
的值。fsi0uk1n5#
在上面的例子中,我使用了datetime列,但类似的查询应该适用于timestamp列。
MAX函数基本上会执行“ORDER BY”payed_until_ts列,并为每个phone_nr选择最新的值。此外,由于“GROUP BY”子句,您将只为每个phone_nr获得一个值。