我已阅读此comment,其中解释了StartFromBeginning
问题及其解决方案。不幸的是,我面临的方法略有不同,我找不到解决方案。
假设我有一个表格,其中包含有关用户的一些基本信息。由于实施,此信息可能会或可能不会重演:
greatest-n-per-group
如您所见,+----+-------------------+----------------+---------------+
| id | user_name | user_name_hash | address |
+----+-------------------+----------------+---------------+
| 1 | peter_jhones | 0xFF321345 | Some Av |
| 2 | sally_whiterspoon | 0x98AB5454 | Certain St |
| 3 | mark_jackobson | 0x0102AB32 | Some Av |
| 4 | mark_jackobson | 0x0102AB32 | Particular St |
+----+-------------------+----------------+---------------+
出现两次,但每个外观的地址都不同。
每隔一段时间,一个ETL进程会查询新的mark_jackobson
并获取每个进程的最新记录。然后,它会将user_name
存储在一个表格中,以表明它已导入某个user_name_hash
user_name
所有内容都以以下查询开头:
+----------------+
| user_name_hash |
+----------------+
| 0xFF321345 |
| 0x98AB5454 |
+----------------+
这样,我可以从我的表中选择新的哈希值。由于我需要查询最近出现的哈希,我将其包装为子查询:
SELECT DISTINCT user_name_hash
FROM my_table
EXCEPT
SELECT user_name_hash
FROM my_hash_table
完美!使用SELECT MAX(id)
FROM my_table
WHERE user_name_hash IN (
SELECT DISTINCT user_name_hash
FROM my_table
EXCEPT
SELECT user_name_hash
FROM my_hash_table)
GROUP BY user_name_hash
的新用户,我可以按如下方式查询地址:
id
从我的角度来看,上面的查询有效,但它似乎不是最佳的。阅读此comment,我注意到我可以使用连接查询相同的数据。由于我没有写出所需的查询,任何人都可以帮助我并指出我的方向吗?
这是我尝试的查询,但没有成功。
SELECT
address,
user_name_hash
FROM my_table
WHERE Id IN (
SELECT MAX(id)
FROM my_table
WHERE user_name_hash IN (
SELECT DISTINCT user_name_hash
FROM my_table
EXCEPT
SELECT user_name_hash
FROM my_hash_table)
GROUP BY user_name_hash)
提前致谢。
编辑>我正在使用 PostgreSQL
答案 0 :(得分:1)
我相信你正在寻找这样的东西:
SELECT
address,
user_name_hash
FROM my_table t1
JOIN (
SELECT MAX(id) maxid
FROM my_table t2
WHERE NOT EXISTS (
SELECT 1
FROM my_hash_table t3
WHERE t2.user_name_hash = t3.user_name_hash
)
GROUP BY user_name_hash
) t ON t1.ID = t.maxid
我使用NOT EXISTS
代替EXCEPT
,因为优化程序更清楚。
答案 1 :(得分:0)
使用左外连接(获取尚未导入的最新记录)可以获得更好的性能,然后计算这些记录的最大ID(HAVING子句中的子查询)。
SELECT t1.address,
t1.user_name_hash,
MAX(id) AS maxid
FROM my_table t1
LEFT JOIN my_hash_table th ON t1.user_name_hash = th.user_name_hash
WHERE th.user_name_hash IS NULL
GROUP BY t1.address,
t1.user_name_hash
HAVING MAX(id) = (SELECT MAX(id)
FROM my_table t1)