我在解决克服其他公司的父/子产品类别的最合理方法时遇到了问题.
可以有3个级别的类别.
即.男士服装(L1)>衬衫(L2)>短袖(L3)(衬衫是短袖的母版,男士服装是衬衫的父母)
ParentCategoryIdis直接在上面的类别的ID.
ParentString是上面所有类别的Id,按级别排序.
(即对于L3产品,它将是L1的Id然后是L2的Id)
表格设置如下.
CREATE TABLE #Categories
(
CategoryId INT
,CompanyId INT
,ParentCategoryId INT
,CategoryName VARCHAR(255)
,ParentString VARCHAR(20)
)
INSERT INTO #Categories VALUES
(123, 12, NULL, 'Mens Clothing', NULL),
(124, 12, 123, 'Shirt', '123-'),
(125, 12, NULL, 'Womens Clothing', NULL),
(126, 12, 125, 'Shirt', '125-'),
(127, 12, 124, 'Short Sleeve', '123-124-'),
(128, 12, NULL, 'Drinks', NULL),
(129, 12, 128, 'Water', '128-')
我需要将所有类别和级别复制到CompanyId 13.
最佳答案 这是一个奇怪的解决方案.
>我们从公司12提供CTE所有东西,
>我们从此表中找到MAX id,然后将其添加到ROW_NUMBER(),
>将ParentString转换为XML,
>选择我们需要的,
并获得可插入Categories表中的输出(见下文):
DECLARE @id int
SELECT @id = MAX(CategoryId) FROM #Categories
;WITH cte AS (
SELECT ROW_NUMBER() OVER (PARTITION BY CompanyId ORDER BY CategoryId) + @id as NewCategoryId,
CategoryId as OldCategoryId,
CompanyId,
ParentCategoryId,
CategoryName,
CAST('<p>'+REPLACE(STUFF(ParentString,LEN(ParentString),1,''),'-','</p><p>')+'</p>' as xml) parentxml
FROM #Categories
WHERE CompanyId = 12
)
SELECT c.NewCategoryId,
13 as CompanyId,
c1.NewCategoryId as NewParentCategoryId,
c.CategoryName,
(
SELECT CAST(f.NewCategoryId as nvarchar(max)) +'-'
FROM cte f
OUTER APPLY (
SELECT t.c.value('.','int') as xpart
FROM c.parentxml.nodes('/p') as t(c)
) x
WHERE OldCategoryId = x.xpart
FOR XML PATH('')
) as ParentString
FROM cte c
LEFT JOIN cte c1
ON c1.OldCategoryId = c.ParentCategoryId
输出:
NewCategoryId CompanyId NewParentCategoryId CategoryName ParentString
130 13 NULL Mens Clothing NULL
131 13 130 Shirt 130-
132 13 NULL Womens Clothing NULL
133 13 132 Shirt 132-
134 13 131 Short Sleeve 130-131-
135 13 NULL Drinks NULL
136 13 135 Water 135-
编辑
如果CategoryId列是自动递增的IDENTITY列,那么最好使用事务并打开IDENTITY_INSERT:
SET IDENTITY_INSERT Categories ON
BEGIN TRANSACTION
...
COMMIT TRANSACTION
SET IDENTITY_INSERT Categories OFf