可能重复:
SQL中的拆分字符串
我在SQL中看到了几个与字符串连接相关的问题.我想知道你将如何处理相反的问题:将昏迷分隔的字符串拆分为数据行:
可以说我有桌子:
userTypedTags(userID,commaSeparatedTags) 'one entry per user
tags(tagID,name)
Run Code Online (Sandbox Code Playgroud)
并希望将数据插入表中
userTag(userID,tagID) 'multiple entries per user
Run Code Online (Sandbox Code Playgroud)
灵感来自数据库中没有哪些标签?题
编辑
谢谢你的答案,实际上有一个值得接受,但我只能选择一个,而Cade Roux提出的递归解决方案对我来说似乎很干净.它适用于SQL Server 2005及更高版本.
对于早期版本的SQL Server,可以使用miies提供的解决方案.对于使用文本数据类型,wcm answer会很有帮助.再次感谢.
我想把'1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 ......'(逗号分隔)拆分成表或表变量.
有没有人有一个函数可以连续返回每一个?
我有一个SQL Server 2008 R2列包含一个字符串,我需要用逗号分隔.我在StackOverflow上看到了很多答案,但它们都不适用于R2.我确保我对任何拆分函数示例都有选择权限.任何帮助非常感谢.
我面临一个问题,即在TVF内声明CTE的maxrecursion选项
这是CTE(一个简单的日历):
DECLARE @DEBUT DATE = '1/1/11', @FIN DATE = '1/10/11';
WITH CTE as(
SELECT @debut as jour
UNION ALL
SELECT DATEADD(day, 1, jour)
FROM CTE
WHERE DATEADD(day, 1, jour) <= @fin)
SELECT jour FROM CTE option (maxrecursion 365)
Run Code Online (Sandbox Code Playgroud)
和TVF:
CREATE FUNCTION [liste_jour]
(@debut date,@fin date)
RETURNS TABLE
AS
RETURN
(
WITH CTE as(
SELECT @debut as jour
UNION ALL
SELECT DATEADD(day, 1, jour)
FROM CTE
WHERE DATEADD(day, 1, jour) <= @fin)
SELECT jour FROM CTE
--option (maxrecursion 365)
) …Run Code Online (Sandbox Code Playgroud) 我有一个包含XML列的表:
CREATE TABLE Batches(
BatchID int,
RawXml xml
)
Run Code Online (Sandbox Code Playgroud)
xml包含以下项目:
<GrobReportXmlFileXmlFile>
<GrobReport>
<ReportHeader>
<OrganizationReportReferenceIdentifier>1</OrganizationReportReferenceIdentifier>
<OrganizationNumber>4</OrganizationNumber>
</ReportHeader>
</GrobReport>
<GrobReport>
<ReportHeader>
<OrganizationReportReferenceIdentifier>2</OrganizationReportReferenceIdentifier>
<OrganizationNumber>4</OrganizationNumber>
</ReportHeader>
</GrobReport>
<GrobReport>
<ReportHeader>
<OrganizationReportReferenceIdentifier>3</OrganizationReportReferenceIdentifier>
<OrganizationNumber>4</OrganizationNumber>
</ReportHeader>
</GrobReport>
<GrobReport>
<ReportHeader>
<OrganizationReportReferenceIdentifier>4</OrganizationReportReferenceIdentifier>
<OrganizationNumber>4</OrganizationNumber>
</ReportHeader>
</GrobReport>
Run Code Online (Sandbox Code Playgroud)
我想要的是生成一个集合,其中包含:
OrganizationReportReferenceNumber OrganizationNumber
================================= ==================
1 4
2 4
3 4
4 4
Run Code Online (Sandbox Code Playgroud)
我试过了:
SELECT
foo.value('/ReportHeader/OrganizationReportReferenceIdentifier') AS ReportIdentifierNumber,
foo.value('/ReportHeader/OrganizationNumber') AS OrginazationNumber
FROM CDRBatches.RawXML.query('/GrobReportXmlFileXmlFile/GrobReport/ReportHeader') foo
Run Code Online (Sandbox Code Playgroud)
但这不起作用.我试过了:
SELECT
foo.value('/ReportHeader/OrganizationReportReferenceIdentifier') AS ReportIdentifierNumber,
foo.value('/ReportHeader/OrganizationNumber') AS OrginazationNumber
FROM RawXML.nodes('/GrobReportXmlFileXmlFile/GrobReport/ReportHeader') bar(foo)
Run Code Online (Sandbox Code Playgroud)
但这不起作用.所述的XPath表达式
/GrobReportXmlFileXmlFile/GrobReport/ReportHeader
Run Code Online (Sandbox Code Playgroud)
是正确的; 在任何其他xml系统中它返回:
<ReportHeader>
<OrganizationReportReferenceIdentifier>1</OrganizationReportReferenceIdentifier>
<OrganizationNumber>4</OrganizationNumber>
</ReportHeader> …Run Code Online (Sandbox Code Playgroud) 我正在使用SQL Server数据库.我有一个包含分隔列表的列,我需要编写一个查询,将列表的值拆分为行.从浏览StackOverflow和网络的其余部分,我知道这是一个常见的问题.事实上,我在这里找到了一个广泛的分析:
http://www.sommarskog.se/arrays-in-sql.html
不幸的是,我在该网站和其他地方看到的每个解决方案都要求我创建一个功能.这不是我的选择 - 我缺乏使用CREATE命令所需的权限.
没有CREATE,我知道我可以使用PARSENAME函数,就像这样(感谢Nathan Bedford 如何分割字符串以便我可以访问项目x?):
SELECT PARSENAME(REPLACE('Hello John Smith', ' ', '.'), 2)
Run Code Online (Sandbox Code Playgroud)
但是,PARSENAME仅适用于4个或更少项目的列表.因此,我的问题是:如何在不在数据库中创建新对象的情况下编写查询来拆分超过4个项目的分隔字符串?
编辑:
感谢大家的快速解答.我可能遗漏了一些重要信息 - 我通过ODBC连接与数据库进行交互.除了CREATE语句之外,似乎还有其他语句不起作用.例如,我似乎无法在一个语句中使用DECLARE来定义将在另一个语句中使用的变量.尽可能接近我的想法,我必须将所有内容都放在一个SELECT语句中(尽管WITH似乎也适用于声明公共表).不幸的是,到目前为止所提出的所有解决方案似乎都需要在SELECT语句之外进行变量声明,而这是不起作用的.请忍受我 - 我正在学习.
嗨,我正在做一些针对遗留数据库的报道,而且我有一点脑屁......
基本上有50个自定义标准,它们作为对应于表格的CSV列完成.
所以说CC5栏的值为'2,6,7,12,8,3,13,1,5,11,'
对着一张桌子 dbo.tbl_custom_code_5
有价值的
code desc
1 Wine
10 Diet Pepsi
11 Other Soft Drink
12 Coffee
13 Tea ....
Run Code Online (Sandbox Code Playgroud)
它就这样......所以我需要做一组/计算一些......
Select [desc], COUNT(b.CC6)
from dbo.tbl_custom_code_6 a
INNER JOIN dbo.Respondent b ON a.code = b.CC6
group by [desc]
Run Code Online (Sandbox Code Playgroud)
由于csv显然不会工作,所以我尝试了第一个愚蠢的事情.
Select [desc], COUNT(b.CC6)
from dbo.tbl_custom_code_6 a
INNER JOIN dbo.Respondent b ON a.code like '%' + b.CC6 + ',%'
group by [desc]
Run Code Online (Sandbox Code Playgroud)
哪个不起作用,即使这样也行不通,因为6会出现等等...
我知道必须有更好的方法来做到这一点.有什么想法吗 ?
我有一个由逗号分隔的ID列表,如:
1,17,25,44,46,67,88
Run Code Online (Sandbox Code Playgroud)
我想将它们转换为表记录(进入临时表)之类的
#tempTable
number_
--------
1
17
25
44
46
67
88
Run Code Online (Sandbox Code Playgroud)
有一个函数,一个表值的函数可以吗?
我为什么要这个?我想使用for INNER JOIN子句(到存储过程)与另一个表,如:
SELECT a,b,c FROM T1
INNER JOIN functionNameWhichReturnsTable
ON functionNameWhichReturnsTable.number_ = T1.a
Run Code Online (Sandbox Code Playgroud)
我无法使用,IN因为我将使用接受NVARCHAR类型参数的存储过程.该参数将提供ID列表.
谢谢
目前我正在进行数据库重新设计项目.该项目的大部分内容是从旧数据库中提取数据并将其导入新数据库.
旧数据库中表中的一列称为"名称".它在一个字段中包含一个名字和一个姓氏(呃).新表有两列; 姓氏和姓氏.我需要提出一种干净,有效的方法将这一列分成两列.
现在我想在同一张桌子上做所有事情然后我可以很容易地将它转移过来.
3列:
我需要做的事情:将名字分成两半并放入姓氏和姓氏
如果有人能够阐明如何做这种事情,我会非常感激,因为我之前没有在SQL中做过这样的事情.
数据库引擎:MySQL
存储引擎:InnoDB
我正在为数据库中的网络的各个方面建模.我们正在处理的一个更烦人的问题是创建子网范围,然后确定给定的IP集合是否在这些范围内.我们当前的模型通过以下列说明了IPv4和IPv6之间的差异:
[subnet_sk] [int] IDENTITY(1,1) NOT NULL,
[ipv6_network] [char](39) NULL,
[ipv6_broadcast] [char](39) NULL,
[ipv4_network] [char](15) NULL,
[ipv4_broadcast] [char](15) NULL,
[network_type] [char](4) NOT NULL
Run Code Online (Sandbox Code Playgroud)
上面的模式做了一些重要的假设,这些假设很重要.我们正在利用完全扩展的IP(192.168.001.001vs. 192.168.1.1)进行存储和比较.我们做出这个决定是因为围绕在SQL服务器中以数字方式存储IPv6地址的问题(bigints是无符号的,这意味着我们必须使用六列来表示IPv6).
给定此表模式,可以很容易地编写一个select语句来确定任一类型的IP是否在表中的范围之间:
select *
from subnet
where '1234:0000:0000:0000:fc12:00ab:0042:1050'
between ipv6_network
and ipv6_broadcast
-- or alternatively for IPv4
select *
from subnet
where '192.168.005.015'
between ipv4_network
and ipv4_broadcast
Run Code Online (Sandbox Code Playgroud)
更为困难的是,IP列表确定哪些IP位于子网范围之间.IP列表将由用户输入提供,不存储在数据库中.显然,对于存储在数据库中的数据,我可以进行类似的连接,如下例所示.
例如,用户可以提供1234:0000:0000:0000:fc12:00ab:0042:1050,192.168.001.001和192.168.1.1.我提出的唯一解决方案是使用表值函数来拆分 IP 列表并使用以下之间执行连接:
-- this only covers the IPv4 addresses from the …Run Code Online (Sandbox Code Playgroud)