如何在第3天之前获取所有数据?'? 下面我有样本数据:
000700- - - 8
015111- - 005 -
019999- - 005 -
A01- 01200- 0 - 5
A01-012000- - 5
A02-015450- - 5
A02-015450- 003 - 1
D08-020700- - 8
D08-020710- - 5
D08-020710- 013 - 1
D08-020710- 013 - 3
这就是我所做的,我得到了正确的信息。但由于删除了一些空格,我无法进行适当的比较以获取Crystal Reports中的数据。
reverse(substring(reverse(a.ProjectionCode),
charindex('-', reverse(a.ProjectionCode)) + 1,
len(reverse(a.ProjectionCode))))) as PhaseCode
答案 0 :(得分:1)
试试这个:
declare @str varchar(200) = 'A02-015450- 003 - 1';
select SUBSTRING(@str, 1, LEN(@str) - CHARINDEX('-', REVERSE(@str), 1));
答案 1 :(得分:0)
您对此输出的期望并不完全清楚。但是猜猜你可以在这里使用PARSENAME,因为你的数据总是正好是三个破折号。请注意,如果您的数据中有任何句点,则无法正常运行。在完美的世界中,这些数据不会像这样在单个列中分隔。它应该分布在列中。你在这里违反了1NF。
declare @Something table
(
SomeValue varchar(50)
)
insert @Something
values
('000700- - - 8')
,('015111- - 005 -')
,('019999- - 005 -')
,('A01- 01200- 0 - 5')
,('A01-012000- - 5')
,('A02-015450- - 5')
,('A02-015450- 003 - 1')
,('D08-020700- - 8')
,('D08-020710- - 5')
,('D08-020710- 013 - 1')
,('D08-020710- 013 - 3 ')
select *
, parsename(replace(SomeValue, '-', '.'), 2)
from @Something
答案 2 :(得分:0)
这应该可以满足您的需求,即使在给定行中有多于或少于3个破折号的情况下也能正常工作。
-- Test Data...
INSERT #TestData (SomeString) VALUES
('000700- - - 8'),
('015111- - 005 -'),
('019999- - 005 -'),
('A01- 01200- 0 - 5'),
('A01-012000- - 5'),
('A02-015450- - 5'),
('A02-015450- 003 - 1'),
('D08-020700- - 8'),
('D08-020710- - 5'),
('D08-020710- 013 - 1'),
('D08-020710- 013 - 3'),
('1-2-3-4-5-6-7-8-9'), -- More than 3 dashes
('zaq12wsx-vfr445tgb'), -- lesst than 3 dashes
('987654321345678'); -- No dashes
-- Query...
SELECT
td.SomeString,
LEFT(td.SomeString, ISNULL(d3.Dash, LEN(td.SomeString) + 1)- 1)
FROM
#TestData td
CROSS APPLY ( VALUES (NULLIF(CHARINDEX('-', td.SomeString, 1), 0)) ) d1 (Dash)
CROSS APPLY ( VALUES (NULLIF(CHARINDEX('-', td.SomeString, d1.Dash + 1), 0)) ) d2 (Dash)
CROSS APPLY ( VALUES (NULLIF(CHARINDEX('-', td.SomeString, d2.Dash + 1), 0)) ) d3 (Dash);
编辑:添加功能和使用代码......
iTVF
CREATE FUNCTION dbo.tfn_TextLeftOfThirdDash
/* =============================================================================================
iTVF that returns all text to the left og the 3rd dash in a string of text
============================================================================================= */
(
@String VARCHAR(8000)
)
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
SELECT
StringRemain = LEFT(@String, ISNULL(d3.Dash, LEN(@String) + 1)- 1)
FROM
( VALUES (NULLIF(CHARINDEX('-', @String, 1), 0)) ) d1 (Dash)
CROSS APPLY ( VALUES (NULLIF(CHARINDEX('-', @String, d1.Dash + 1), 0)) ) d2 (Dash)
CROSS APPLY ( VALUES (NULLIF(CHARINDEX('-', @String, d2.Dash + 1), 0)) ) d3 (Dash);
GO
如何使用该功能...
SELECT
td.SomeString,
l3d.StringRemain
FROM
#TestData td
CROSS APPLY dbo.tfn_TextLeftOfThirdDash(td.SomeString) l3d;
HTH, 杰森
答案 3 :(得分:0)
用于搜索字符串的tsql函数charindex接受从哪里开始的参数。可以使用另一个对charindex的调用来计算此起始位置。
SELECT
SUBSTRING(col, 1,
CHARINDEX('-', col,
CHARINDEX('-', col,
CHARINDEX('-', col)+1
)+1
)-1
)
FROM table
答案 4 :(得分:0)
SQL Server本身没有任何内容可以确定字符或字符串的第n个位置。我的方法是创建自己的方法。像这样:
CREATE FUNCTION [dbo].[nthOccurencePos](@input VARCHAR(128), @delimiter CHAR(1), @nth INT)
RETURNS INT
BEGIN
DECLARE @result INT;
WITH cteExample AS
(
--Find the index of the first delimiter
SELECT 1 AS rowCounter, CHARINDEX(@delimiter, @input, 1) delPos
UNION ALL
--Move over one character and find the index of the next delimiter
SELECT rowCounter + 1, CHARINDEX(@delimiter, @input, delPos + 1)
FROM cteExample
WHERE delPos > 0 --When you come up empty, stop
)
SELECT @result = delPos FROM cteExample WHERE rowCounter = @nth;
RETURN @result;
END
现在使用此函数来获取第3个连字符之前的所有内容,如下所示:
DECLARE @tbl TABLE(sample VARCHAR(128))
INSERT @tbl VALUES
('000700- - - 8')
,('015111- - 005 -')
,('019999- - 005 -')
,('A01- 01200- 0 - 5')
,('A01-012000- - 5')
,('A02-015450- - 5')
,('A02-015450- 003 - 1')
,('D08-020700- - 8')
,('D08-020710- - 5')
,('D08-020710- 013 - 1')
,('D08-020710- 013 - 3 ');
SELECT LEFT(sample, dbo.nthOccurencePos(sample, '-', 3) - 1) BeforeHyphen3
FROM @tbl;
虽然在您的情况下不使用它,但更常见的是需要在分隔字符串中的第n列数据。例如:
DECLARE @delim NVARCHAR(128);
SET @delim = 'abcdefg-hijklmnop-qrstuv-wxyz';
SELECT SUBSTRING(@delim, dbo.nthOccurencePos(@delim, '-', 2) + 1, dbo.nthOccurencePos(@delim, '-', 3) - dbo.nthOccurencePos(@delim, '-', 2) - 1) as thirdColumn