我有一个层次结构,已经能够采用以下格式(从中获取的电子表格是一团糟):
我需要从AllLevels列中获取值并创建一个具有以下列名称的新表:
RegionLevel1 RegionLevel2 RegionLevel3 RegionLevel4 CountryCode FullPath HierarchyName
这就是窍门-第一个'|'之前的所有内容始终为Level1,最后一个'|'之后的值始终是Level4。但是看看“中央” | “波兰” | PL。应该这样
1级-中央,2级-波兰,3级-NULL,4级-PL
我以为我对此有些了解,但事实并非如此。有人可以帮忙吗?
这是我用来从原始表创建此CTE的位置:
with child as
(
select ParentCode
, countrycode
, Cast (countrycode as varchar(100)) as Level
from [dbo].[rawCountryHierarchy]
where CountryCode IN (SELECT DISTINCT TRIM(LEFT(BillingLocation, CHARINDEX('-', BillingLocation)-1)) FROM FactSales)
union all
select e.parentcode
, e.countrycode
, cast (cast(e.countrycode as varchar(100))+' | '+level as varchar(100)) as level
from child m
join [dbo].[rawCountryHierarchy] e
on m.parentcode= e.countrycode
)
--insert into [dbo].[DimCountryHierarchy]
select c.ParentCode, c.CountryCode AS rawCountryCode, cast (cast(c.ParentCode as varchar(100))+' | '+level as varchar(100)) as AllLevels, CASE WHEN Level like '%|%' THEN trim(right(level, charindex('|', reverse(level))-1)) END AS CountryCode, r.HierarchyName
from child c
inner join rawRegion on c.parentcode = rawRegion.RegionCode
left join rawCountryHierarchy r on CASE WHEN Level like '%|%' THEN trim(right(level, charindex('|', reverse(level))-1)) END = r.CountryCode
order by AllLevels
option (maxrecursion 0)
在这里,我从以下国家/地区获取国家/地区代码:
WHERE CountryCode IN (SELECT DISTINCT TRIM(LEFT(BillingLocation, CHARINDEX('-', BillingLocation)-1)) FROM FactSales)
所以实际上代表了最低水平。
编辑: 我尝试填充的新表中的列如下:
RegionLevel1 RegionLevel2 RegionLevel3 RegionLevel4 CountryCode FullPath HierarchyName
RegionLevel1始终是图片AllLevels列中的第一个值。 CountryCode始终是最后一个“ |”之后的最后一个值在所有级别列中。在AllLevels列的First和Last值之间,RegionLevel2,RegionLevel3和RegionLevel4列将从左到右填充(即,在第一行的情况下,它看起来像:RegionLevel1-Africa,RegionLevel2-Export,RegionLevel3-WestAfrica ,RegionLevel4-NULL,CountryCode-NG),然后用AllLevels列填充FullPath,而HierarchyName则填充新表中的同一列。
答案 0 :(得分:0)
您要解决的问题对我来说似乎无法解决。有时数据太脏了,在这里可能就是这种情况。您如何知道Level1-中央,Level2-波兰,Level3-NULL,Level4-PL和Level1-中央,Level2-波兰,Level3-PL之间的区别 问题在于,数据没有使用级别3和4的正确分隔符输入。 如果以Central | Poland || PL(针对第4级)或Central | Poland | PL(针对第3级)的形式出现,则可以解决,但是使用您提供的这些数据,无法准确知道3和4级我可以看到
答案 1 :(得分:0)
此方法使用DelimitedSplit8K
拆分值,然后旋转它们。可能有点矫kill过正,但这是一个不同的选择,可能值得尝试:
USE Sandbox;
GO
CREATE TABLE dbo.AllLevels (ID int IDENTITY(1,1), --I ASSUME you have an ID column
Levels varchar(8000));
INSERT INTO dbo.AllLevels (Levels)
VALUES ('Africa | Export | West Africa | NG'),
('Austria | ATALL | AT'),
('Central | HU');
GO
WITH Split AS(
SELECT AL.ID, AL.Levels,
LTRIM(RTRIM(DS.Item)) AS [Level],
DS.ItemNumber AS LevelNumber,
MAX(DS.ItemNumber) OVER (PARTITION BY ID) AS MaxLevel
FROM dbo.AllLevels AL
CROSS APPLY dbo.DelimitedSplit8K(AL.Levels,'|') DS),
Pivots AS(
SELECT ID,
MAX(CASE WHEN LevelNumber = 1 AND LevelNumber < MaxLevel THEN [Level] END) AS Level1,
MAX(CASE WHEN LevelNumber = 2 AND LevelNumber < MaxLevel THEN [Level] END) AS Level2,
MAX(CASE WHEN LevelNumber = 3 AND LevelNumber < MaxLevel THEN [Level] END) AS Level3,
MAX(CASE WHEN LevelNumber = 4 OR LevelNumber = MaxLevel THEN [Level] END) AS Level4
FROM Split
GROUP BY ID)
SELECT *
FROM Pivots P
JOIN dbo.AllLevels AL ON P.ID = AL.ID;
GO
DROP TABLE dbo.AllLevels;