我有一个表格,其数据如下所示:
product_id | filter_id
__________________
4525 5066
4525 5068
4525 5091
4526 5066
4526 5068
4526 5094
4527 5066
4527 5068
4527 5094
4528 5066
4528 5071
4528 5078
对于每种产品实际上是三个过滤器的组,例如product 4525有过滤器5066,5068和5091.
第二组和第三组是与不同产品(4526和4527)绑定的完全相同的过滤器组(5066,5068和5094)。
我想让每个唯一的过滤器集只有一次(换句话说,我想删除重复的filter_ids集)。我真的不在乎product_id会发生什么,我只希望我的三个filter_ids的唯一集合与一个键组合在一起。
例如,这也将:
new_id | filter_id
__________________
1 5066
1 5068
1 5091
2 5066
2 5068
2 5094
3 5066
3 5071
3 5078
我希望我解释得很好。
谢谢。
答案 0 :(得分:1)
请尝试以下查询,这比我预期的要长一些。到目前为止还没有得到任何其他逻辑!!!
select
distinct filter_id,
DENSE_RANK() over(order by sc) new_id
from(
select *,
(SELECT ' ' + cast(filter_id as nvarchar(10))
FROM tbl b where b.product_id=a.product_id order by filter_id
FOR XML PATH('')) SC
From tbl a
)x
order by new_id
/ --------------其他方式------------------ /
SELECT
DENSE_RANK() OVER (ORDER BY PRODUCT_ID) new_id,
filter_id
FROM
Table1
WHERE product_id in (
SELECT MIN(product_id) FROM(
SELECT
product_id,
SUM(filter_id*RN) OVER (PARTITION BY PRODUCT_ID) SM
FROM(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY filter_id) RN
FROM Table1
)x
)xx GROUP BY SM)
答案 1 :(得分:0)
Select dense_rank()
over(order by product_id asc),filter_id
from table
答案 2 :(得分:0)
如果我理解这个问题,预期结果只有产品4525,4526和4528的filter_id,因为4526和4527具有相同的filter_id,因此只需要其中一个,在这种情况下,此查询将执行:< / p>
SELECT product_id
, dense_rank() OVER (ORDER BY PRODUCT_ID) new_id
, filter_id
FROM table1 c
WHERE NOT EXISTS (SELECT 1
FROM table1 a
LEFT JOIN table1 b ON a.product_id < b.product_id
WHERE b.product_id = c.product_id
GROUP BY a.product_id, b.product_id
HAVING COUNT(DISTINCT a.filter_id)
= COUNT(CASE WHEN a.filter_id = b.filter_id THEN 1
ELSE NULL
END));
要获得结果,第一步是删除带有完整重复的filter_ID列表的产品。为了获得这些产品,子查询检查每个产品对,以查看一个中filter_id的数量是否等于这对夫妇共享的filter_id。
如果您的产品具有不同数量的过滤器,并且应该从结果中删除完全包含在另一产品的过滤器列表中的过滤器列表的产品,例如,如果使用基础数据
product_id | filter_id
-----------+----------
4525 | 5066
4525 | 5068
4525 | 5091
4526 | 5066
4526 | 5068
预期结果是
new_id | filter_id
-------+----------
1 | 5066
1 | 5068
1 | 5091
查询需要更改为
SELECT product_id
, dense_rank() OVER (ORDER BY PRODUCT_ID) new_id
, filter_id
FROM table1 c
WHERE NOT EXISTS (SELECT b.product_id
FROM table1 a
LEFT JOIN table1 b ON a.product_id < b.product_id
WHERE b.product_id IS NOT NULL
AND b.product_id = c.product_id
GROUP BY a.product_id, b.product_id
HAVING COUNT(DISTINCT a.filter_id)
= COUNT(CASE WHEN a.filter_id = b.filter_id THEN 1
ELSE NULL
END)
OR COUNT(DISTINCT b.filter_id)
= COUNT(CASE WHEN a.filter_id = b.filter_id THEN 1
ELSE NULL
END));
我提出了一个与TechDo的第二个相似的查询,在他之后9个小时。即使结果相似,但由于想法不同,我的想法是将filter_id的值与math连接
;WITH B AS (
SELECT Product_ID
, filter_id = filter_id - MIN(filter_id) OVER (PARTITION BY NULL)
, _ID = Row_Number() OVER (PARTITION BY Product_ID ORDER BY filter_id) - 1
, N = CEILING(LOG10(MAX(filter_id) OVER (PARTITION BY NULL)
- MIN(filter_id) OVER (PARTITION BY NULL)))
FROM table1 a
), G1 AS (
SELECT Product_ID
, _ID = SUM(Filter_ID * POWER(10, N * _ID))
FROM B
GROUP BY Product_ID
), G2 AS (
SELECT Product_ID = MIN(Product_ID)
FROM G1
GROUP BY _ID
)
SELECT g2.product_id
, dense_rank() OVER (ORDER BY g2.PRODUCT_ID) new_id
, a.filter_id
FROM G2
INNER JOIN table1 a ON g2.product_id = a.product_id;
第一个CTE
做了很多工作:
filter_id
等级降低(从0减少到n-1位,具体取决于数据的范围)_ID
)N
)在以下CTE
中,这些值用于使用SUM
生成过滤器连接,公式SUM(Filter_ID * POWER(10, N * _ID))
每隔N个位置放置一个缩小的filter_id,例如,由提供的数据提供OP我们得到filter_id的最大差值是28,所以N是2,结果是(为了便于阅读,增加了点数)
Product_ID _ID
----------- -----------
4525 25.02.00
4526 28.02.00
4527 28.02.00
4528 12.05.00
使用的公式使得不同的过滤器组之间的碰撞不可能,但需要更大的空间来计算,如果filter_id的范围很大,它可以达到整数的限制。