Tsql 创建相关列的集群
我有一个名为Stores的表,其中包含列:Tsql 创建相关列的集群,tsql,Tsql,我有一个名为Stores的表,其中包含列: StoreCode NVARCHAR(10), OldStoreCode NVARCHAR(10) 以下是我的数据示例: | StoreCode | OldStoreCode | |-----------|--------------| | A | B | | B | A | | D | E | | E | F
StoreCode NVARCHAR(10),
OldStoreCode NVARCHAR(10)
以下是我的数据示例:
| StoreCode | OldStoreCode |
|-----------|--------------|
| A | B |
| B | A |
| D | E |
| E | F |
| M | K |
| J | K |
| K | L |
|-----------|--------------|
我想创建相关商店的集群。关联存储表示StoreCodes和OldStoreCodes之间存在单向关系
预期结果表:
| StoreCode | ClusterId |
|-----------|-----------|
| A | 1 |
| B | 1 |
| D | 2 |
| E | 2 |
| F | 2 |
| M | 3 |
| K | 3 |
| J | 3 |
| L | 3 |
|-----------|-----------|
没有最大跳数。可能有一个存储代码a,它有一个OldStoreCode B,它有一个OldStoreCode C,它有一个OldStoreCode D等等
我如何才能像这样对存储进行群集?这应该可以做到:
样本数据:
IF OBJECT_ID('tempdb..#Temp1') IS NOT NULL
BEGIN
DROP TABLE #Temp1;
END;
CREATE TABLE #Temp1(StoreCode NVARCHAR(10)
, OldStoreCode NVARCHAR(10));
INSERT INTO #Temp1(StoreCode
, OldStoreCode)
VALUES
('A'
, 'B'),
('B'
, 'A'),
('D'
, 'E'),
('E'
, 'F'),
('M'
, 'K'),
('J'
, 'K'),
('K'
, 'L');
查询:
;WITH A -- get all distinct new and old storecodes
AS (
SELECT StoreCode
FROM #Temp1
UNION
SELECT OldStoreCode
FROM #Temp1),
B -- give a unique number id to each store code
AS (SELECT rn = RANK() OVER(ORDER BY StoreCode)
, StoreCode
FROM A),
C -- combine the store codes and the unique number id's in one table
AS (SELECT b2.rn AS StoreCodeID
, t.StoreCode
, b1.rn AS OldStoreCodeId
, t.OldStoreCode
FROM #Temp1 AS t
LEFT OUTER JOIN B AS b1 ON t.OldStoreCode = b1.StoreCode
LEFT OUTER JOIN B AS b2 ON t.StoreCode = b2.StoreCode),
D -- assign a row number for each entry in the data set
AS (SELECT rn = RANK() OVER(ORDER BY StoreCode)
, *
FROM C),
E -- derive first and last store in the path
AS (SELECT FirstStore = d2.StoreCode
, LastStore = d1.OldStoreCode
, GroupID = d1.OldStoreCodeId
FROM D AS d1
RIGHT OUTER JOIN D AS d2 ON d1.StoreCodeID = d2.OldStoreCodeId
AND d1.rn - 1 = d2.rn
WHERE d1.OldStoreCode IS NOT NULL) ,
F -- get the stores wich led to the last store with one hop
AS (SELECT C.StoreCode
, E.GroupID
FROM E
INNER JOIN C ON E.LastStore = C.OldStoreCode)
-- combine to get the full grouping
SELECT A.StoreCode, ClusterID = DENSE_RANK() OVER (ORDER BY A.GroupID) FROM (
SELECT C.StoreCode,F.GroupID FROM C INNER JOIN F ON C.OldStoreCode = F.StoreCode
UNION
SELECT * FROM F
UNION
SELECT E.LastStore,E.GroupID FROM E) AS A ORDER BY StoreCode, ClusterID
结果:
试着这样做:
编辑:由OP根据注释进行更改
结果
ID Val
1 A
1 B
3 D
3 E
3 F
5 J
5 K
5 L
5 M
请解释一下相关存储的逻辑。我不知道您需要什么…从示例中看,您似乎正在将商店与OldStore关联,但将任何OldStore关联到另一个OldStore M->K,K->L将M关联到L。您确定这是目的吗?@Shnugo如果其中一个在StoreCode列中,另一个在OldStoreCode列中,则两个商店是相关的,在一个record@Anthony我故意以这种情况为例。考虑到关系M->K,J->K,K->L,我需要说,商店M,K,J,L形成了一个集群。你能不能更具建设性地解释一下为什么投反对票,这样我才能改进?嗨,我没有投反对票,也不知道为什么+1从我这边我对您的解决方案进行了以下添加,并达到了预期的结果。我对您的解决方案进行了以下添加,并达到了预期的结果。@ekremsekerci,抱歉,没有看到您的添加内容。。。很高兴看到这对你有用。如果问题解决了,在验收单上打勾是很好的。快乐编码!我为您的解决方案添加了以下内容,并达到了预期的效果。使结果表成为名为ClusterKeys的CTE:clusterId作为选择ClusterKey,MINID作为ID从ClusterKeys组按ClusterKey选择r.ID,r.Val从clusterId中选择c.ID=r的内部联接相关r。ID@ekremsekerci,是的,多一个CTE将允许您轻松地使用派生表。
ID Val
1 A
1 B
3 D
3 E
3 F
5 J
5 K
5 L
5 M