如果我對這個問題理解的很好,預期的結果只有產品4525,4526和4528的filter_id,因爲4526和4527具有相同的filter_id,所以只需要其中的一個,在這種情況下,該查詢將執行:
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));
SQLFiddle demo
要獲得結果,第一步是使用完整的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));
SQLFiddle Demo
我想出了神似TechDo的第二個,在他之後經過九年小時查詢。即使結果是相似的,因爲想法不同的是,我的想法是用數學來Concat的過濾器_id值
;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;
SQLFiddle demo
第一CTE
做了很多工作:
filter_id
的等級降低(根據數據的範圍從0減少到n-1個數字)
- 屬於泰德以便在產品中過濾器上的順序號(
_ID
)
- 計算最大數量的減少過濾器_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的範圍很大,則可以達到極限。
你可以檢查下面的查詢... – Azar
在測試案例中,你有4個不同的產品ID,是預期的結果是否正確或應該有另一組過濾器new_id 4? – Serpiton
@Serpiton在我的情況下,它不會超過3個,因爲這是我使用的過濾器的數量。但可能會更多。我還注意到可能會出現較少的過濾器組。 – xpy