我读过这个comment,它解释了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 |
+----+-------------------+----------------+---------------+
正如你所看到的,mark_jackobson
出现了两次,虽然每个外观的地址都不同。
每隔一段时间,一个ETL进程会查询新的user_name
s并获取每个user_name_hash
s的最新记录。后来,它将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
完善!使用我的新用户的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)
s,我可以查询地址如下:
comment
从我的角度来看,上面的查询是有效的,但它似乎并不是最优的。读这个SELECT
tb1.address,
tb1.user_name_hash
FROM my_table tb1
INNER JOIN my_table tb2
ON tb1.user_name_hash = tb2.user_name_hash
LEFT JOIN my_hash_table ht
ON tb1.user_name_hash = ht.user_name_hash AND tb1.id > tb2.id
WHERE ht.user_name_hash IS NULL;
,我注意到我可以使用连接查询相同的数据。由于我没有写出所需的查询,任何人都可以帮助我并指出我的方向吗?
这是我尝试过的查询,没有成功。
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
提前致谢。
编辑>我正在使用PostgreSQL
我相信你正在寻找这样的东西:
NOT EXISTS
我使用EXCEPT
而不是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)
,因为优化器更清楚。
您可以使用左外连接获得更好的性能(以获取尚未导入的最新记录),然后计算这些记录的最大ID(HAVING子句中的子查询)。
qazxswpoi