以状态为例,我当前的数据看起来像
StateAbbrev | NumOfResults
----------- ------------
MD | 5
VA | 2
DC | 7
MD|VA | 2
CA|NY|VA | 1
我希望输出以下内容
StateName | NumOfResults
--------- ------------
Maryland | 5
Virginia | 2
District of Columbia | 7
Maryland,Virginia | 2
California,New York,Virginia | 1
我有一个可以将StateAbbrev映射到StateName
的表我可以创建一个函数,如果管道分隔的ID并且吐出逗号分隔的列表,只会取列表,但我有超过1个表与此场景,所以我正在寻找一个更清洁的解决方案。 谢谢!
答案 0 :(得分:1)
我使用以下UDF来处理拆分(通过4guysfromrolla)
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[Split]
(
@List nvarchar(2000),
@SplitOn nvarchar(5)
)
RETURNS @RtnValue table
(
Id int identity(1,1),
Value nvarchar(100)
)
AS
BEGIN
While (Charindex(@SplitOn,@List)>0)
Begin
Insert Into @RtnValue (value)
Select
Value = ltrim(rtrim(Substring(@List,1,Charindex(@SplitOn,@List)-1)))
Set @List = Substring(@List,Charindex(@SplitOn,@List)+len(@SplitOn),len(@List))
End
Insert Into @RtnValue (Value)
Select Value = ltrim(rtrim(@List))
Return
END
以下是如何使用UDF的示例:
select [Value] from [dbo].Split('CA|NY|VA', '|')
哪个会返回一个包含3行的表,每个状态一个。
更新:
以下是完成第一次翻译的完整调用:
declare @cslist varchar(2056)
select @cslist = coalesce(@cslist+',', '') + translated_states.full_state
FROM (
select T2.full_state from [dbo].Split('CA|NY|VA', '|') as T1
JOIN test as T2
on T2.abbr_state = T1.[Value]
) translated_states
select @cslist
如果您对需要更新的内容有任何疑问,请与我联系,以使其适用于您的表而不是我的测试表。
答案 1 :(得分:0)
您可以编写C#函数,然后使用SQLCLR执行此操作:http://msdn.microsoft.com/en-us/library/ms345136%28SQL.90%29.aspx
或者您可以编写一个T-SQL函数来执行此操作。
答案 2 :(得分:0)
我想出了以下内容,但我不得不使用临时表来完成它;由于某种原因,子查询不适用于SUBSTRING。
DECLARE @T TABLE ( col VARCHAR(1000) )
INSERT INTO @T
( col
)
SELECT 'MD'
UNION ALL
SELECT 'MD|CA'
UNION ALL
SELECT 'MD|CA|VA'
DECLARE @states TABLE
(
abbr VARCHAR(2) ,
StateName VARCHAR(10)
)
INSERT INTO @states
SELECT 'MD' ,
'Maryland'
UNION ALL
SELECT 'CA' ,
'California'
UNION ALL
SELECT 'VA' ,
'Virginia'
SELECT col ,
word = SUBSTRING('|' + col + '|', Number + 1,
CHARINDEX('|', '|' + col + '|', Number + 1) - Number
- 1) ,
Number
INTO #tmp
FROM ( SELECT /*use a table of numbers if you have one instead of this subquery*/
ROW_NUMBER() OVER ( ORDER BY ( ac1.Object_ID ) ) AS Number
FROM Master.sys.columns ac1
) Numbers
CROSS APPLY @t t
WHERE Number >= 1
AND Number < LEN('|' + col + '|') - 1
AND SUBSTRING('|' + col + '|', Number, 1) = '|'
ORDER BY col ,
Number
SELECT t1.col ,
StateName = REPLACE(( SELECT StateName AS [data()]
FROM #tmp t
JOIN @states s ON t.word = s.abbr
WHERE t1.col = t.col
ORDER BY COL ,
Number
FOR
XML PATH('')
), ' ', '|')
FROM #tmp t1
DROP TABLE #tmp
答案 3 :(得分:0)
这是一个非UDF解决方案,它使用Numbers表,XML和CROSS APPLY(两次):
DECLARE @Numbers TABLE (Num INT);
INSERT INTO @Numbers VALUES (1);
INSERT INTO @Numbers VALUES (2);
INSERT INTO @Numbers VALUES (3);
INSERT INTO @Numbers VALUES (4);
INSERT INTO @Numbers VALUES (5);
INSERT INTO @Numbers VALUES (6);
INSERT INTO @Numbers VALUES (7);
INSERT INTO @Numbers VALUES (8);
INSERT INTO @Numbers VALUES (9);
DECLARE @Results TABLE (StateAbbrevs VARCHAR(255), NumOfResults INT);
INSERT INTO @Results VALUES ('MD', 5);
INSERT INTO @Results VALUES ('VA', 2);
INSERT INTO @Results VALUES ('DC', 7);
INSERT INTO @Results VALUES ('MD|VA', 2);
INSERT INTO @Results VALUES ('CA|NY|VA', 1);
DECLARE @Abbrev TABLE (StateAbbrev VARCHAR(2), StateName VARCHAR(255));
INSERT INTO @Abbrev VALUES ('MD', 'Maryland');
INSERT INTO @Abbrev VALUES ('VA', 'Virginia');
INSERT INTO @Abbrev VALUES ('DC', 'District of Columbia');
INSERT INTO @Abbrev VALUES ('CA', 'California');
INSERT INTO @Abbrev VALUES ('NY', 'New York');
--SELECT * FROM @Results;
--
--SELECT * FROM @Abbrev;
SELECT STUFF(StateNames, 1, 1, '') AS StateNames,
NumOfResults
FROM @Results AS RESULTS0
CROSS APPLY ( SELECT ',' + ABBREV.StateName
FROM ( SELECT PVT.StateAbbrev,
RESULTS.StateAbbrevs
FROM @Results AS RESULTS
CROSS APPLY ( SELECT SUBSTRING(RESULTS.StateAbbrevs, NUMBERS.Num, CHARINDEX('|', RESULTS.StateAbbrevs + '|', NUMBERS.Num) - NUMBERS.Num) AS StateAbbrev
FROM @Numbers AS NUMBERS
WHERE NUMBERS.Num <= LEN(RESULTS.StateAbbrevs)
AND SUBSTRING('|' + RESULTS.StateAbbrevs, NUMBERS.Num, 1) = '|'
) AS PVT
) AS X
LEFT JOIN @Abbrev AS ABBREV ON ABBREV.StateAbbrev = X.StateAbbrev
WHERE StateAbbrevs = RESULTS0.StateAbbrevs
FOR
XML PATH('')
) AS Y ( StateNames )