我的数据库中有一个名为“Notes”的字段。它包含一个逗号分隔的值列表。
我想执行一个只返回“注释”字段中的第一个值的 SELECT 查询。
此查询还将返回数据库中的其他字段。
例如
SELECT Name, Phone, Notes (only the first value)
FROM Table1
这可能吗,我该怎么做?
我的数据库中有一个名为“Notes”的字段。它包含一个逗号分隔的值列表。
我想执行一个只返回“注释”字段中的第一个值的 SELECT 查询。
此查询还将返回数据库中的其他字段。
例如
SELECT Name, Phone, Notes (only the first value)
FROM Table1
这可能吗,我该怎么做?
您可以CHARINDEX
使用SUBSTRING
:
SELECT Name, Phone, SUBSTRING(Notes, 1, CHARINDEX(',', Notes)) AS first_value
FROM Table1
演示
DECLARE @csv varchar(50)
SET @csv = 'comma after this, and another,'
SELECT SUBSTRING(@csv, 1, CHARINDEX(',', @csv)) AS first_value
结果
| 第一个值 | -------------------- | 后面的逗号 |
如评论中所述,您应该规范化您的结构,并且在单个属性中存储的值不超过一个。
SELECT Name, Phone, Left(Notes, CharIndex(',', Notes + ',')) FirstNote
FROM Table1
您需要Notes + ','
CharIndex 中的位才能正常工作 - 请参阅此示例(我已包含 njk 的答案)
with Table1(Name, Phone, Notes) as (
select 'abc', '123', 'Some,notes,here' union all
select 'abd', '124', 'Single-note' union all
select 'abe', '125', '' union all
select 'syz', '126', null
)
---
SELECT Name, Phone, Left(Notes, CharIndex(',', Notes + ',')-1) FirstNote
,SUBSTRING(Notes, 0, CHARINDEX(',', Notes)) AS njk
FROM Table1
结果
Name Phone FirstNote njk
---- ----- --------------- ---------------
abc 123 Some Some
abd 124 Single-note
abe 125
syz 126 NULL NULL
SELECT name,
phones,
split_part(notes, ',', 1) as first_notes
FROM Table1
从逗号分隔列表中选择值的解决方案
我正在寻找一个更一般的答案(不仅仅是第一个字段,而是一个任意指定的),所以我修改了 Kermit 的答案并将其放入一个函数中。这是以防万一它有助于节省其他人的时间
CREATE FUNCTION [dbo].[fnGetFieldXFromDelimitedList] (@SearchIn nvarchar(max)
, @Delimiter char(1), @FieldNum int ) RETURNS nvarchar(max) as BEGIN
/*
fnGetFieldXFromDelimitedList(@SearchIn, @Delimiter, @FieldNum)
Returns the Nth value (specified by @FieldNum, first is 1 not 0)
from @SearchIn assuming @SearchIn is a list of multiple values
delimited by @Delimiter
DECLARE @SearchIn nvarchar(max) = 'F1, Field 2, F3,, F5, F6, F7'
DECLARE @Delimiter char(1) = ','
DECLARE @FieldNum int = 7
--*/
--SELECT dbo.fnGetFieldXFromDelimitedList ('F1, Field 2, F3,, F5, F6, F7', ',', 5)
DECLARE @PosStart int = 1 --SUBSTRING(SearchIn, StartPos, StrLen) considers 1 the first character
DECLARE @PosEnd INT = LEN(@SearchIn)
DECLARE @TempString nvarchar(max) = CONCAT(@SearchIn, @Delimiter)
DECLARE @TempNum INT = 1
DECLARE @RetVal nvarchar(max) = ''
--SElECT SUBSTRING(@SearchIn, 1, 1)
SET @PosEnd = CHARINDEX(@Delimiter, @TempString, @PosStart + LEN(@Delimiter))
WHILE @TempNum < @FieldNum AND @PosStart > 0 AND @PosStart < LEN(@TempString) BEGIN
SET @PosStart = CHARINDEX(@Delimiter, @TempString, @PosStart) + LEN(@Delimiter)
SET @PosEnd = CHARINDEX(@Delimiter, @TempString, @PosStart)
SET @TempNum = @TempNum + 1
--SELECT @PosStart, @PosEnd , @TempNum
END --WHILE
IF @TempNum = @FieldNum AND @PosEnd > 0 BEGIN
SET @RetVal = SUBSTRING(@TempString, @PosStart, @PosEnd - @PosStart)
END ELSE BEGIN
SET @RetVal = NULL
END
--SELECT @RetVal
RETURN @RetVal
END