问题
考虑具有以下模式的表DailySales
:
列名 | 类型 |
---|---|
date_id | 日期 |
make_name | varchar |
lids_id | int |
pantern_id | int |
该表包含出售产品的日期和名称,以及出售其出售的铅和合作伙伴的ID。该名称仅由小写英文字母组成。对于每个date_id
和make_name
,您需要找到独特的lead_id
和独特的partner_id
的数量。结果表应以任何顺序返回。
解释
考虑以下样本DailySales
表:
date_id | make_name | lead_id | pantern_id |
---|---|---|---|
2020-12-8 | 丰田 | 0 | 1 |
2020-12-8 | 丰田 | 1 | 0 |
2020-12-8 | 丰田 | 1 | 2 |
2020-12-7 | 丰田 | 0 | 2 |
2020-12-7 | 丰田 | 0 | 1 |
2020-12-8 | 本田 | 1 | 2 |
2020-12-8 | 本田 | 2 | 1 |
2020-12-7 | 本田 | 0 | 1 |
2020-12-7 | 本田 | 1 | 2 |
2020-12-7 | 本田 | 2 | 1 |
对于此输入,预期的输出为:
date_id | make_name | unique_leads | unique_partners |
---|---|---|---|
2020-12-8 | 丰田 | 2 | 3 |
2020-12-7 | 丰田 | 1 | 2 |
2020-12-8 | 本田 | 2 | 2 |
2020-12-7 | 本田 | 3 | 2 |
在这里,每一行都代表一个独特的日期和make_name,并且每个组合的唯一铅和合作伙伴计数。
解决方案
让我们讨论解决这个问题的两种不同的方法,强调了它们的优势和缺点,并解释了它们的基本结构。
使用计数(不同)
这种方法直接计算了date_id
和make_name
的每种组合的独特的lead_id
和partner_id
。
SELECT
date_id,
make_name,
COUNT(DISTINCT lead_id) [unique_leads],
COUNT(DISTINCT partner_id) [unique_partners]
FROM DailySales
GROUP BY
date_id,
make_name
此查询相当简单且易于理解。它通过对date_id
和make_name
进行分组来进行工作,然后计算每个组中不同的潜在客户和合作伙伴。但是,在大型数据集中,COUNT(DISTINCT)
可能会很慢。此查询运行时为1073ms,击败了Leetcode上其他提交的22.3%。
使用dense_rank()
此方法首先在date_id
和make_name
定义的每个组中排名lead_id
和partner_id
,然后选择每个组的最大等级作为不同的潜在客户或合作伙伴的数量。
WITH ranks AS (
SELECT
date_id,
make_name,
DENSE_RANK() OVER (PARTITION BY date_id, make_name ORDER BY lead_id) [lead_rank],
DENSE_RANK() OVER (PARTITION BY date_id, make_name ORDER BY partner_id) [partner_rank]
FROM DailySales
)
SELECT
date_id,
make_name,
(SELECT MAX(lead_rank) FROM ranks r WHERE r.date_id = ds.date_id AND r.make_name = ds.make_name) [unique_leads],
(SELECT MAX(partner_rank) FROM ranks r WHERE r.date_id = ds.date_id AND r.make_name = ds.make_name) [unique_partners]
FROM DailySales ds
GROUP BY
date_id,
make_name
这种方法虽然更复杂,但却消除了对COUNT(DISTINCT)
的需求,这可以在某些情况下提高性能。但是,在处理大型数据集时,将子征服的包含在选择子句中可能会导致性能降解。此查询运行时为2467ms,击败了Leetcode上其他提交的5.17%。
结论
这两种方法都解决了问题,但是它们的性能可能会根据数据集的大小和分布而有所不同。 COUNT(DISTINCT)
方法更简单,并且在LeetCode的平台上表现更好,因此在这种情况下它是首选解决方案。但是,根据数据分布和数据库引擎的优化等几个因素,在现实世界中的性能可能会有所不同。
您可以在LeetCode中找到原始问题。
有关更有见地的解决方案和与技术相关的内容,请随时在Beacons page上与我联系。