SQL Server列拆分
我刚刚开始使用SQL中的查询,所以我还没有真正体验过。SQL Server列拆分
我试图查看这个,但我不明白它的大部分(并不能说,如果它真的适合我的问题),所以我很想解释你会做什么解决它和为什么!
我正在处理数据库,如果你问我,有时候会非常低效地处理数据。
数据库结构如下:
USE [TestDatabase]
CREATE TABLE [dbo].[fruits](
...(other columns)
[diffruits1] int, NOT NULL
[diffruits2] [varchar](100) NULL,
...
)
此一列(diffruits2)会说这样的事情:
"apples=1000, bananas=2, oranges=1, blueberries=102"
现在我的目标是使用例如对于IF语句或其他计算,来自苹果的1000个值(或来自蓝莓的102个值) 。我认为需要从varchar转换为int。
像这样:
IF diffruits1=103
BEGIN
IF apples >= 1000
BEGIN
example.statement
END
IF blueberries =10
BEGIN
example.statement2
END
END
类似的东西。我知道我可以将'='和','之间的列分开,但说实话,我只是不知道如何。我想用它来做一个程序。
如果您无法更改表格结构,则可以使用字符串拆分功能来创建可以使用的视图。
创建和填充示例表(请保存我们这一步在你未来的问题):如果您使用的是SQL服务器2016
CREATE TABLE fruits
(
diffruits1 int,
diffruits2 varchar(100)
)
INSERT INTO fruits VALUES (1, 'apples=1000, bananas=2, oranges=1, blueberries=102')
,您可以使用内置的STRING_SPLIT
功能。对于较低版本,您需要先创建函数。
对于这个答案,我chosed使用基于杰夫MODEN的spliter功能,从阿龙贝特朗的文章Split strings the right way – or the next best way采取:
CREATE FUNCTION dbo.SplitStrings
(
@List NVARCHAR(MAX),
@Delimiter NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING AS
RETURN
WITH E1(N) AS (SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1),
E2(N) AS (SELECT 1 FROM E1 a, E1 b),
E4(N) AS (SELECT 1 FROM E2 a, E2 b),
E42(N) AS (SELECT 1 FROM E4 a, E2 b),
cteTally(N) AS (SELECT 0 UNION ALL SELECT TOP (DATALENGTH(ISNULL(@List,1)))
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E42),
cteStart(N1) AS (SELECT t.N+1 FROM cteTally t
WHERE (SUBSTRING(@List,t.N,1) = @Delimiter OR t.N = 0))
SELECT Item = SUBSTRING(@List, s.N1, ISNULL(NULLIF(CHARINDEX(@Delimiter,@List,s.N1),0)-s.N1,8000))
FROM cteStart s;
一旦你拥有了拆分字符串函数,你可以创建这样的观点:
CREATE VIEW vw_Splitted AS
SELECT diffruits1,
LTRIM(RTRIM(LEFT(Item, CHARINDEX('=', Item)-1))) As Name,
CAST(RIGHT(Item, LEN(Item) - CHARINDEX('=', Item)) As int) As Value
FROM fruits
CROSS APPLY dbo.SplitStrings(diffruits2, ',')
测试视图:
SELECT *
FROM vw_Splitted
结果:
diffruits1 Name Value
1 apples 1000
1 bananas 2
1 oranges 1
1 blueberries 102
你可以看到现场演示上rextester:
非常感谢!这就是我需要的 –
[很高兴帮助: - )](http://meta.stackoverflow.com/questions/291325/how-to-show-appreciation-to-a-user-on-stackoverflow/291327#291327 ) –
这是类似于琐佩莱德的答案,但我想说明你如何可以使用分离功能在程序运行的条件更你自找的。
rextester演示:http://rextester.com/QXM5706
create table t (id int, diffruits2 varchar(8000));
insert into t values
(1, 'apples=1, bananas=2, oranges=3, blueberries=10')
,(2, 'apples=1000, bananas=2, oranges=1, blueberries=102');
select
t.Id
, Ordinal = s.ItemNumber
, Fruit = ltrim(left(s.Item,charindex('=',s.Item)-1))
, Quantity = stuff(s.Item,1,charindex('=',s.Item),'')
from t
cross apply dbo.delimitedsplit8K(diffruits2,', ') s
go
回报:
+----+---------+-------------+----------+
| Id | Ordinal | Fruit | Quantity |
+----+---------+-------------+----------+
| 1 | 1 | apples | 1 |
| 1 | 2 | bananas | 2 |
| 1 | 3 | oranges | 3 |
| 1 | 4 | blueberries | 10 |
| 2 | 1 | apples | 1000 |
| 2 | 2 | bananas | 2 |
| 2 | 3 | oranges | 1 |
| 2 | 4 | blueberries | 102 |
+----+---------+-------------+----------+
分割字符串参考:
- Tally OH! An Improved SQL 8K “CSV Splitter” Function - Jeff Moden
- Splitting Strings : A Follow-Up - Aaron Bertrand
- Split strings the right way – or the next best way - Aaron Bertrand
string_split()
in SQL Server 2016 : Follow-Up #1 - Aaron Bertrand
而你也可以用它在你的程序像这样:
go
create procedure dbo.fruitful (@id int) as
begin;
set nocount, xact_abort on;
select
t.Id
, Ordinal = s.ItemNumber
, Fruit = ltrim(left(s.Item,charindex('=',s.Item)-1))
, Quantity = stuff(s.Item,1,charindex('=',s.Item),'')
into #temp_fruit
from t
cross apply dbo.delimitedsplit8K(diffruits2,', ') s
where t.id = @id;
if exists (
select 1
from #temp_fruit
where Fruit='apples'
and Quantity>=1000
)
begin;
/* steal an apple, or other code */
select 1 as AppleStolen;
end;
if exists (
select 1
from #temp_fruit
where Fruit='blueberries'
and Quantity=10
)
begin;
/* give them 2 more blueberries, just to be nice. or other code. */
select 2 as BlueberriesAdded;
end;
end;
go
与ID为1的添加字符串的例子程序:
exec dbo.fruitful 1;
r eturns:
+------------------+
| BlueberriesAdded |
+------------------+
| 2 |
+------------------+
并为您的原始字符串:
exec dbo.fruitful 2;
回报:
+-------------+
| AppleStolen |
+-------------+
| 1 |
+-------------+
非常感谢你! –
@JoeyR乐于帮忙! – SqlZim
你的问题不是clear.see参考知道如何提出一个完善的问题链接: https://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/ – TheGameiswar
您可以先对结构进行标准化,或者是给定结构且不能更改? –
将这样的数据存储在数据库表中是* bug *。拆分不足以解析这些数据。在加载到数据库之前,您应该解析数据并将其存储在精心设计的表格中。所有你需要的是一个带有'FruitName','Count'和ThatParentTableID列的独立表格 –