我需要帮助。 有关CHARINDEX,PATINDEX,SUBSTRING,LEFT和RIGHT上的SQL的问题。
我有一些字符串需要根据位置和定界符进行拆分。使用其中一些作为列名,另一部分作为数据。并根据行ID对其进行分组。然后根据需要对这些值求和。
样本数据,ID,字符串
1 20:4:10:1:20:3:
2 20:1:
3 10:3:
4 30:4:40:1:50:3:
所需的结果是
id 10 20 30 40 50
1 1 7
2 1
3 3
4 4 1 3
数据:
CREATE TABLE #Split (ID int, SplitString varchar(450))
Insert into #Split (ID, SplitString) values
(1, '20:4:10:1:20:3:'),
(2, '20:1:'),
(3, '10:3:'),
(4, '30:4:40:1:50:3:')
select * From #Split
DROP TABLE #Split
任何帮助将不胜感激!
数据也可能是这样的:
CREATE TABLE #Split (ID int, String1 varchar(10), String1Quantity int, String2 varchar(10), String2Quantity int, String3 VARCHAR(10), String3Quantity int, String4 varchar(10), String4Quantity int, String5 varchar(10), String5Quantity int)
Insert into #Split (ID, String1, String1Quantity, String2, String2Quantity, String3, String3Quantity, String4, String4Quantity, String5, String5Quantity) values
(1,'20',4,'10',1,'20',3, null, null, null, null),
(2,'20',1,null,null,null,null, null, null, null, null),
(3,'10',3,null,null,null,null, null, null, null, null),
(4,'30',4,'40',1,'50',3, null, null, null, null)
select * From #Split
DROP TABLE #Split
答案 0 :(得分:1)
首先,正如我在评论中所写:解决方案是修复损坏的数据模型。有关更多信息,请阅读Is storing a delimited list in a database column really that bad?,您将在这里看到很多答案,为什么这个问题的答案是绝对是!
话虽这么说,但我知道很多时候,由于许多不同的原因,改变数据库结构是不可行的,即使这样做可以解决许多问题。
现在,基于您的字符串操作函数,我假设您正在使用SQL Server(请注意,对于每个sql问题,您都应始终指定rdbms和版本,如果确实需要,请使用database-agnostic跨数据库解决方案)。
因此,根据您的假设,您最好的选择是使用Jeff Moden's DelimitedSplit8K UDF将字符串分成表格。
此函数将返回一个包含两列的表-一列用于子字符串,一列用于其在源字符串中的索引-这正是开始构造要获取的结果所需要的。
因此,基于该功能,几个常见的表表达式,数据透视表和条件聚合,我想出了以下解决方案:
WITH CTE1 AS
(
SELECT Id,
CAST(IIF(ItemNumber % 2 = 0, Item, NULL) as int) As Data,
IIF(ItemNumber % 2 = 1, Item, NULL) As Name,
IIF(ItemNumber % 2 = 0, ItemNumber - 1, ItemNumber) As PairNumber
FROM #Split
CROSS APPLY dbo.DelimitedSplit8K(SplitString, ':')
WHERE Item IS NOT NULL
AND Item <> ''
), CTE2 AS
(
SELECT Id, PairNumber, MAX(Data) As Data, MAX(Name) As Name
FROM CTE1
GROUP BY Id, PairNumber
)
, CTEPivot AS
(
SELECT Id, [10], [20], [30], [40], [50]
FROM
(
SELECT Id, SUM(Data) As Data, Name
FROM CTE2
GROUP BY Id, Name
) D
PIVOT
(
AVG(Data)
FOR Name IN ([10], [20], [30], [40], [50])
) AS PivotTable
)
SELECT Id,
MAX([10]) As [10],
MAX([20]) As [20],
MAX([30]) As [30],
MAX([40]) As [40],
MAX([50]) As [50]
FROM CTEPivot
GROUP BY Id;
结果:
+----+----+----+----+----+----+
| Id | 10 | 20 | 30 | 40 | 50 |
+----+----+----+----+----+----+
| 1 | 1 | 7 | | | |
+----+----+----+----+----+----+
| 2 | | 1 | | | |
+----+----+----+----+----+----+
| 3 | 3 | | | | |
+----+----+----+----+----+----+
| 4 | | | 4 | 1 | 3 |
+----+----+----+----+----+----+
答案 1 :(得分:0)
我想出了一个对后一种数据不太好的解决方案,有更好的方法吗?
CREATE TABLE #Split (ID int, String1 varchar(10), String1Quantity int, String2 varchar(10), String2Quantity int, String3 VARCHAR(10), String3Quantity int, String4 varchar(10), String4Quantity int, String5 varchar(10), String5Quantity int)
Insert into #Split (ID, String1, String1Quantity, String2, String2Quantity, String3, String3Quantity, String4, String4Quantity, String5, String5Quantity) values
(1,'20',4,'10',1,'20',3, '20', 10, '20', 3),
(2,'20',1,'10',3,null,null, null, null, null, null),
(3,'10',3,'10',3,null,null, null, null, null, null),
(4,'30',4,'40',1,'50',3, '40', 8, '10', 1)
select
ID,
CASE
WHEN String1 = '10' and String2 = '10' and String3 = '10' and String4 = '10' and String5 = '10' THEN SUM(String1Quantity+String2Quantity+String3Quantity+String4Quantity+String5Quantity)
WHEN String1 = '10' and String2 = '10' and String3 = '10' and String4 = '10' THEN SUM(String1Quantity+String2Quantity+String3Quantity+String4Quantity)
WHEN String1 = '10' and String2 = '10' and String3 = '10' and String5 = '10' THEN SUM(String1Quantity+String2Quantity+String3Quantity+String5Quantity)
WHEN String1 = '10' and String3 = '10' and String4 = '10' and String5 = '10' THEN SUM(String1Quantity+String3Quantity+String3Quantity+String4Quantity)
WHEN String2 = '10' and String3 = '10' and String4 = '10' and String5 = '10' THEN SUM(String2Quantity+String3Quantity+String4Quantity+String5Quantity)
WHEN String1 = '10' and String2 = '10' and String3 = '10' THEN SUM(String1Quantity+String2Quantity+String3Quantity)
WHEN String1 = '10' and String2 = '10' and String4 = '10' THEN SUM(String1Quantity+String2Quantity+String4Quantity)
WHEN String1 = '10' and String2 = '10' and String5 = '10' THEN SUM(String1Quantity+String2Quantity+String5Quantity)
WHEN String1 = '10' and String3 = '10' and String4 = '10' THEN SUM(String1Quantity+String3Quantity+String4Quantity)
WHEN String1 = '10' and String3 = '10' and String5 = '10' THEN SUM(String1Quantity+String3Quantity+String5Quantity)
WHEN String1 = '10' and String4 = '10' and String5 = '10' THEN SUM(String1Quantity+String4Quantity+String5Quantity)
WHEN String2 = '10' and String3 = '10' and String4 = '10' THEN SUM(String2Quantity+String3Quantity+String4Quantity)
WHEN String2 = '10' and String3 = '10' and String5 = '10' THEN SUM(String2Quantity+String3Quantity+String5Quantity)
WHEN String2 = '10' and String4 = '10' and String5 = '10' THEN SUM(String2Quantity+String4Quantity+String5Quantity)
WHEN String3 = '10' and String4 = '10' and String5 = '10' THEN SUM(String3Quantity+String4Quantity+String5Quantity)
WHEN String3 = '10' and String5 = '10' THEN SUM(String3Quantity+String5Quantity)
WHEN String3 = '10' and String4 = '10' THEN SUM(String3Quantity+String4Quantity)
WHEN String2 = '10' and String5 = '10' THEN SUM(String2Quantity+String5Quantity)
WHEN String2 = '10' and String4 = '10' THEN SUM(String2Quantity+String4Quantity)
WHEN String2 = '10' and String3 = '10' THEN SUM(String2Quantity+String3Quantity)
WHEN String1 = '10' and String5 = '10' THEN SUM(String1Quantity+String5Quantity)
WHEN String1 = '10' and String4 = '10' THEN SUM(String1Quantity+String4Quantity)
WHEN String1 = '10' and String3 = '10' THEN SUM(String1Quantity+String3Quantity)
WHEN String1 = '10' and String2 = '10' THEN SUM(String1Quantity+String2Quantity)
WHEN String5 = '10' THEN SUM(String5Quantity)
WHEN String4 = '10' THEN SUM(String4Quantity)
WHEN String3 = '10' THEN SUM(String3Quantity)
WHEN String2 = '10' THEN SUM(String2Quantity)
WHEN String1 = '10' THEN SUM(String1Quantity)
END AS '10',
CASE
WHEN String1 = '20' and String2 = '20' and String3 = '20' and String4 = '20' and String5 = '20' THEN SUM(String1Quantity+String2Quantity+String3Quantity+String4Quantity+String5Quantity)
WHEN String1 = '20' and String2 = '20' and String3 = '20' and String4 = '20' THEN SUM(String1Quantity+String2Quantity+String3Quantity+String4Quantity)
WHEN String1 = '20' and String2 = '20' and String3 = '20' and String5 = '20' THEN SUM(String1Quantity+String2Quantity+String3Quantity+String5Quantity)
WHEN String1 = '20' and String3 = '20' and String4 = '20' and String5 = '20' THEN SUM(String1Quantity+String3Quantity+String3Quantity+String4Quantity)
WHEN String2 = '20' and String3 = '20' and String4 = '20' and String5 = '20' THEN SUM(String2Quantity+String3Quantity+String4Quantity+String5Quantity)
WHEN String1 = '20' and String2 = '20' and String3 = '20' THEN SUM(String1Quantity+String2Quantity+String3Quantity)
WHEN String1 = '20' and String2 = '20' and String4 = '20' THEN SUM(String1Quantity+String2Quantity+String4Quantity)
WHEN String1 = '20' and String2 = '20' and String5 = '20' THEN SUM(String1Quantity+String2Quantity+String5Quantity)
WHEN String1 = '20' and String3 = '20' and String4 = '20' THEN SUM(String1Quantity+String3Quantity+String4Quantity)
WHEN String1 = '20' and String3 = '20' and String5 = '20' THEN SUM(String1Quantity+String3Quantity+String5Quantity)
WHEN String1 = '20' and String4 = '20' and String5 = '20' THEN SUM(String1Quantity+String4Quantity+String5Quantity)
WHEN String2 = '20' and String3 = '20' and String4 = '20' THEN SUM(String2Quantity+String3Quantity+String4Quantity)
WHEN String2 = '20' and String3 = '20' and String5 = '20' THEN SUM(String2Quantity+String3Quantity+String5Quantity)
WHEN String2 = '20' and String4 = '20' and String5 = '20' THEN SUM(String2Quantity+String4Quantity+String5Quantity)
WHEN String3 = '20' and String4 = '20' and String5 = '20' THEN SUM(String3Quantity+String4Quantity+String5Quantity)
WHEN String3 = '20' and String5 = '20' THEN SUM(String3Quantity+String5Quantity)
WHEN String3 = '20' and String4 = '20' THEN SUM(String3Quantity+String4Quantity)
WHEN String2 = '20' and String5 = '20' THEN SUM(String2Quantity+String5Quantity)
WHEN String2 = '20' and String4 = '20' THEN SUM(String2Quantity+String4Quantity)
WHEN String2 = '20' and String3 = '20' THEN SUM(String2Quantity+String3Quantity)
WHEN String1 = '20' and String5 = '20' THEN SUM(String1Quantity+String5Quantity)
WHEN String1 = '20' and String4 = '20' THEN SUM(String1Quantity+String4Quantity)
WHEN String1 = '20' and String3 = '20' THEN SUM(String1Quantity+String3Quantity)
WHEN String1 = '20' and String2 = '20' THEN SUM(String1Quantity+String2Quantity)
WHEN String5 = '20' THEN SUM(String5Quantity)
WHEN String4 = '20' THEN SUM(String4Quantity)
WHEN String3 = '20' THEN SUM(String3Quantity)
WHEN String2 = '20' THEN SUM(String2Quantity)
WHEN String1 = '20' THEN SUM(String1Quantity)
END AS '20',
CASE
WHEN String1 = '30' and String2 = '30' and String3 = '30' and String4 = '30' and String5 = '30' THEN SUM(String1Quantity+String2Quantity+String3Quantity+String4Quantity+String5Quantity)
WHEN String1 = '30' and String2 = '30' and String3 = '30' and String4 = '30' THEN SUM(String1Quantity+String2Quantity+String3Quantity+String4Quantity)
WHEN String1 = '30' and String2 = '30' and String3 = '30' and String5 = '30' THEN SUM(String1Quantity+String2Quantity+String3Quantity+String5Quantity)
WHEN String1 = '30' and String3 = '30' and String4 = '30' and String5 = '30' THEN SUM(String1Quantity+String3Quantity+String3Quantity+String4Quantity)
WHEN String2 = '30' and String3 = '30' and String4 = '30' and String5 = '30' THEN SUM(String2Quantity+String3Quantity+String4Quantity+String5Quantity)
WHEN String1 = '30' and String2 = '30' and String3 = '30' THEN SUM(String1Quantity+String2Quantity+String3Quantity)
WHEN String1 = '30' and String2 = '30' and String4 = '30' THEN SUM(String1Quantity+String2Quantity+String4Quantity)
WHEN String1 = '30' and String2 = '30' and String5 = '30' THEN SUM(String1Quantity+String2Quantity+String5Quantity)
WHEN String1 = '30' and String3 = '30' and String4 = '30' THEN SUM(String1Quantity+String3Quantity+String4Quantity)
WHEN String1 = '30' and String3 = '30' and String5 = '30' THEN SUM(String1Quantity+String3Quantity+String5Quantity)
WHEN String1 = '30' and String4 = '30' and String5 = '30' THEN SUM(String1Quantity+String4Quantity+String5Quantity)
WHEN String2 = '30' and String3 = '30' and String4 = '30' THEN SUM(String2Quantity+String3Quantity+String4Quantity)
WHEN String2 = '30' and String3 = '30' and String5 = '30' THEN SUM(String2Quantity+String3Quantity+String5Quantity)
WHEN String2 = '30' and String4 = '30' and String5 = '30' THEN SUM(String2Quantity+String4Quantity+String5Quantity)
WHEN String3 = '30' and String4 = '30' and String5 = '30' THEN SUM(String3Quantity+String4Quantity+String5Quantity)
WHEN String3 = '30' and String5 = '30' THEN SUM(String3Quantity+String5Quantity)
WHEN String3 = '30' and String4 = '30' THEN SUM(String3Quantity+String4Quantity)
WHEN String2 = '30' and String5 = '30' THEN SUM(String2Quantity+String5Quantity)
WHEN String2 = '30' and String4 = '30' THEN SUM(String2Quantity+String4Quantity)
WHEN String2 = '30' and String3 = '30' THEN SUM(String2Quantity+String3Quantity)
WHEN String1 = '30' and String5 = '30' THEN SUM(String1Quantity+String5Quantity)
WHEN String1 = '30' and String4 = '30' THEN SUM(String1Quantity+String4Quantity)
WHEN String1 = '30' and String3 = '30' THEN SUM(String1Quantity+String3Quantity)
WHEN String1 = '30' and String2 = '30' THEN SUM(String1Quantity+String2Quantity)
WHEN String5 = '30' THEN SUM(String5Quantity)
WHEN String4 = '30' THEN SUM(String4Quantity)
WHEN String3 = '30' THEN SUM(String3Quantity)
WHEN String2 = '30' THEN SUM(String2Quantity)
WHEN String1 = '30' THEN SUM(String1Quantity)
END AS '30',
CASE
WHEN String1 = '40' and String2 = '40' and String3 = '40' and String4 = '40' and String5 = '40' THEN SUM(String1Quantity+String2Quantity+String3Quantity+String4Quantity+String5Quantity)
WHEN String1 = '40' and String2 = '40' and String3 = '40' and String4 = '40' THEN SUM(String1Quantity+String2Quantity+String3Quantity+String4Quantity)
WHEN String1 = '40' and String2 = '40' and String3 = '40' and String5 = '40' THEN SUM(String1Quantity+String2Quantity+String3Quantity+String5Quantity)
WHEN String1 = '40' and String3 = '40' and String4 = '40' and String5 = '40' THEN SUM(String1Quantity+String3Quantity+String3Quantity+String4Quantity)
WHEN String2 = '40' and String3 = '40' and String4 = '40' and String5 = '40' THEN SUM(String2Quantity+String3Quantity+String4Quantity+String5Quantity)
WHEN String1 = '40' and String2 = '40' and String3 = '40' THEN SUM(String1Quantity+String2Quantity+String3Quantity)
WHEN String1 = '40' and String2 = '40' and String4 = '40' THEN SUM(String1Quantity+String2Quantity+String4Quantity)
WHEN String1 = '40' and String2 = '40' and String5 = '40' THEN SUM(String1Quantity+String2Quantity+String5Quantity)
WHEN String1 = '40' and String3 = '40' and String4 = '40' THEN SUM(String1Quantity+String3Quantity+String4Quantity)
WHEN String1 = '40' and String3 = '40' and String5 = '40' THEN SUM(String1Quantity+String3Quantity+String5Quantity)
WHEN String1 = '40' and String4 = '40' and String5 = '40' THEN SUM(String1Quantity+String4Quantity+String5Quantity)
WHEN String2 = '40' and String3 = '40' and String4 = '40' THEN SUM(String2Quantity+String3Quantity+String4Quantity)
WHEN String2 = '40' and String3 = '40' and String5 = '40' THEN SUM(String2Quantity+String3Quantity+String5Quantity)
WHEN String2 = '40' and String4 = '40' and String5 = '40' THEN SUM(String2Quantity+String4Quantity+String5Quantity)
WHEN String3 = '40' and String4 = '40' and String5 = '40' THEN SUM(String3Quantity+String4Quantity+String5Quantity)
WHEN String3 = '40' and String5 = '40' THEN SUM(String3Quantity+String5Quantity)
WHEN String3 = '40' and String4 = '40' THEN SUM(String3Quantity+String4Quantity)
WHEN String2 = '40' and String5 = '40' THEN SUM(String2Quantity+String5Quantity)
WHEN String2 = '40' and String4 = '40' THEN SUM(String2Quantity+String4Quantity)
WHEN String2 = '40' and String3 = '40' THEN SUM(String2Quantity+String3Quantity)
WHEN String1 = '40' and String5 = '40' THEN SUM(String1Quantity+String5Quantity)
WHEN String1 = '40' and String4 = '40' THEN SUM(String1Quantity+String4Quantity)
WHEN String1 = '40' and String3 = '40' THEN SUM(String1Quantity+String3Quantity)
WHEN String1 = '40' and String2 = '40' THEN SUM(String1Quantity+String2Quantity)
WHEN String5 = '40' THEN SUM(String5Quantity)
WHEN String4 = '40' THEN SUM(String4Quantity)
WHEN String3 = '40' THEN SUM(String3Quantity)
WHEN String2 = '40' THEN SUM(String2Quantity)
WHEN String1 = '40' THEN SUM(String1Quantity)
END AS '40',
CASE
WHEN String1 = '50' and String2 = '50' and String3 = '50' and String4 = '50' and String5 = '50' THEN SUM(String1Quantity+String2Quantity+String3Quantity+String4Quantity+String5Quantity)
WHEN String1 = '50' and String2 = '50' and String3 = '50' and String4 = '50' THEN SUM(String1Quantity+String2Quantity+String3Quantity+String4Quantity)
WHEN String1 = '50' and String2 = '50' and String3 = '50' and String5 = '50' THEN SUM(String1Quantity+String2Quantity+String3Quantity+String5Quantity)
WHEN String1 = '50' and String3 = '50' and String4 = '50' and String5 = '50' THEN SUM(String1Quantity+String3Quantity+String3Quantity+String4Quantity)
WHEN String2 = '50' and String3 = '50' and String4 = '50' and String5 = '50' THEN SUM(String2Quantity+String3Quantity+String4Quantity+String5Quantity)
WHEN String1 = '50' and String2 = '50' and String3 = '50' THEN SUM(String1Quantity+String2Quantity+String3Quantity)
WHEN String1 = '50' and String2 = '50' and String4 = '50' THEN SUM(String1Quantity+String2Quantity+String4Quantity)
WHEN String1 = '50' and String2 = '50' and String5 = '50' THEN SUM(String1Quantity+String2Quantity+String5Quantity)
WHEN String1 = '50' and String3 = '50' and String4 = '50' THEN SUM(String1Quantity+String3Quantity+String4Quantity)
WHEN String1 = '50' and String3 = '50' and String5 = '50' THEN SUM(String1Quantity+String3Quantity+String5Quantity)
WHEN String1 = '50' and String4 = '50' and String5 = '50' THEN SUM(String1Quantity+String4Quantity+String5Quantity)
WHEN String2 = '50' and String3 = '50' and String4 = '50' THEN SUM(String2Quantity+String3Quantity+String4Quantity)
WHEN String2 = '50' and String3 = '50' and String5 = '50' THEN SUM(String2Quantity+String3Quantity+String5Quantity)
WHEN String2 = '50' and String4 = '50' and String5 = '50' THEN SUM(String2Quantity+String4Quantity+String5Quantity)
WHEN String3 = '50' and String4 = '50' and String5 = '50' THEN SUM(String3Quantity+String4Quantity+String5Quantity)
WHEN String3 = '50' and String5 = '50' THEN SUM(String3Quantity+String5Quantity)
WHEN String3 = '50' and String4 = '50' THEN SUM(String3Quantity+String4Quantity)
WHEN String2 = '50' and String5 = '50' THEN SUM(String2Quantity+String5Quantity)
WHEN String2 = '50' and String4 = '50' THEN SUM(String2Quantity+String4Quantity)
WHEN String2 = '50' and String3 = '50' THEN SUM(String2Quantity+String3Quantity)
WHEN String1 = '50' and String5 = '50' THEN SUM(String1Quantity+String5Quantity)
WHEN String1 = '50' and String4 = '50' THEN SUM(String1Quantity+String4Quantity)
WHEN String1 = '50' and String3 = '50' THEN SUM(String1Quantity+String3Quantity)
WHEN String1 = '50' and String2 = '50' THEN SUM(String1Quantity+String2Quantity)
WHEN String5 = '50' THEN SUM(String5Quantity)
WHEN String4 = '50' THEN SUM(String4Quantity)
WHEN String3 = '50' THEN SUM(String3Quantity)
WHEN String2 = '50' THEN SUM(String2Quantity)
WHEN String1 = '50' THEN SUM(String1Quantity)
END AS '50'
From #Split
Group by Id, String1, String2, String3, string4, String5
drop table #Split