上下文是我们有一个userid和一个transactionid,但有时userid会发生变化,但是由于客户端的设置,transactionid保持不变(当两者都应该是常量时),有时候transactionid会改变但是userid不会(所以我们不能只使用transactionid)。
所以我们希望得到一些我们可以用作实际ID的东西。新列(即实际ID)仅用于对行进行分组,因此它可以是任意(唯一)值。排序无关紧要。
示例:
| userid | transactionid |
|--------|---------------|
| A | 1 |
| A | 2 |
| A | 3 |
| B | 2 |
| B | 2 |
| C | 4 |
| D | 5 |
| D | 5 |
| D | 6 |
| E | 6 |
| E | 7 |
| F | 4 |
可能成为:
| userid | transactionid | actualid |
|--------|---------------|----------|
| A | 1 | A |
| A | 2 | A |
| A | 3 | A |
| B | 2 | A |
| B | 2 | A |
| C | 4 | C |
| D | 5 | E |
| D | 5 | E |
| D | 6 | E |
| E | 6 | E |
| E | 7 | E |
| F | 4 | C |
我们正在使用Presto,因此存在一些限制(没有临时表,聚合查询中没有DISTINCT等)
这里显示了使用Python中的for循环的解决方案:http://nbviewer.ipython.org/urls/gist.githubusercontent.com/jamesmcm/2554d5d4498b5d46d42d/raw/587ff552c34027e85ee199d5d8e5cb192e5550d1/gistfile1.txt
但我们需要Presto的解决方案。
这最初是在Gist上写的:https://gist.github.com/jamesmcm/9b9a559eb9f69405c04a
如果您想要正确格式化表格。
答案 0 :(得分:1)
这可以使用Windows函数而不是连接来完成,并且需要比@David建议的更多步骤。
使用以下示例
uid | tid
B | 2
B | 3
B | 4
A | 3
E | 1
可以做到
SELECT
*,
MIN(minuid) OVER (PARTITION BY mintid order by 1) as final_id
FROM(
SELECT
tid,
uid,
MIN(uid) OVER (PARTITION BY tid order by 1) as minuid,
MIN(tid) OVER (PARTITION BY uid order by 1) as mintid
FROM
log
)
这应该返回正确的ID
uid | tid | minuid | mintid | final_id
B | 2 | B | 2 | A
B | 3 | A | 2 | A
B | 4 | B | 2 | A
A | 3 | A | 3 | A
E | 1 | E | 1 | E
答案 1 :(得分:0)
我们首先找到分配给每个transactionid(tid)的用户标识(uid)。有多种方法可以选择此分配,但将使用最小(最小)用户ID:
SELECT tid, min(uid) xid
FROM log
GROUP BY tid
这导致以下分配:
tid | xid
-----+-----
1 | A
2 | A
3 | A
4 | C
5 | D
6 | D
7 | E
(7 rows)
现在我们有了作业,我们可以将它们加入到原始表中:
SELECT a.uid, a.tid, b.xid
FROM log a
JOIN (
SELECT tid, min(uid) xid
FROM log
GROUP BY tid
) b
ON (a.tid = b.tid)
ORDER BY 1, 2;
输出:
uid | tid | xid
-----+-----+-----
A | 1 | A
A | 2 | A
A | 3 | A
B | 2 | A
B | 2 | A
C | 4 | C
D | 5 | D
D | 5 | D
D | 6 | D
E | 6 | D
E | 7 | E
F | 4 | C
(12 rows)