2015-02-24 7 views
0

Поэтому у меня есть таблица, которая выглядит следующим образом:Substring диапазон вспыхнуть SQL Server 2008 R2

Order/item  Price 
2001/1-10  $1000 
2001/11-13  $ 500 
2002/1-20 + 22 $2500 
2003    $2000 

И я хочу взять данные из заказа/элемента и создать диапазон выглядеть следующим образом:

Order/item 
2001/1 
2001/2 
2001/3 

и так далее ... Как вы видите, может быть знаком «+», указывающий диапазон есть ху, а также г ...

мои переменные и подстрока навыки ограничены. Мой макрос думал, что нужно взять первое число после знака «/» и +1 до него, пока не дойду до второго номера. Но есть также записи без знака «/», а затем как обрабатывать номера «+». Также первое число после знака «/» может составлять от 1 до 4 цифр. Извините, если это базовое. Я знаю, что есть похожие вопросы, но ничего, что действительно помогло мне понять.

EDIT:

Так что по этому поводу ... не заботясь о порядке/one_item формат ... позволяет сказать, что поле всегда будет порядок/элемент-элемент без пробелов + 's и т.д. ... . Я хочу, чтобы взять первый элемент (поэтому все цифры после «/», но до «-», а затем добавить к нему 1, пока не достигнет 2-го значения элемента, так что таблица будет выглядеть следующим образом:.

order/item new_col 
2001/1-10  1 
2001/1-10  2 
2001/1-10  3 
2001/1-10  4 
2001/1-10  5 
2001/1-10  6 
2001/1-10  7 
2001/1-10  8 
2001/1-10  9 
2001/1-10  10 

Это, наверное, было бы проще сделать, я бы подумал.

+0

Это выглядит слишком comlpex, чтобы быть достигнутым (легко и разумно) в SQL. – DavidG

+0

Да, это сложно, и это нормально, если кто-то хочет опубликовать комплексное решение. – user3486773

+1

То, что я имею в виду, гораздо проще выполнять на языке программирования (например, C#). – DavidG

ответ

0

Это должно работать с вашей упрощенной версией. e CTE генерирует (большой) диапазон чисел, который затем соединяется обратно к строке, которая была разделена на составляющие ее части.

DECLARE @OrderItem VARCHAR(100) = '2001/1-10' 

;WITH Nums AS 
(
    SELECT n = ROW_NUMBER() OVER (ORDER BY [object_id]) 
    FROM sys.all_objects 

) 
SELECT SUBSTRING(@OrderItem, 0, CHARINDEX('/', @OrderItem)), 
     n 
FROM nums 
WHERE n BETWEEN CAST(SUBSTRING(SUBSTRING(@OrderItem, 6, 100), 0, CHARINDEX('-', SUBSTRING(@OrderItem, 6, 100))) AS INT) 
AND CAST(SUBSTRING(SUBSTRING(@OrderItem, 6, 100), CHARINDEX('-', SUBSTRING(@OrderItem, 6, 100))+1, 100) AS INT) 

Так если у вас есть таблица с именем Orders, который имеет столбцы, называемые OrderItem и Price, то вы можете присоединиться к ним вместе, как это:

;WITH Nums AS 
(
    SELECT n = ROW_NUMBER() OVER (ORDER BY [object_id]) 
    FROM sys.all_objects 

) 

SELECT SUBSTRING(Orders.OrderItem, 0, CHARINDEX('/', Orders.OrderItem)) AS [Order], 
     n AS Item, 
     Price 
FROM Orders 
CROSS APPLY nums 
WHERE n BETWEEN CAST(SUBSTRING(SUBSTRING(Orders.OrderItem, 6, 100), 0, CHARINDEX('-', SUBSTRING(Orders.OrderItem, 6, 100))) AS INT) 
AND CAST(SUBSTRING(SUBSTRING(Orders.OrderItem, 6, 100), CHARINDEX('-', SUBSTRING(Orders.OrderItem, 6, 100))+1, 100) AS INT) 
0

Вы можете создать функцию, чтобы получить диапазон для каждого ряд

CREATE FUNCTION dbo.GetRange (@range varchar(10)) 
RETURNS @RangeTable TABLE (RangeNumber int) AS BEGIN 

    DECLARE @StartRange int, @EndRange int 

    SELECT @StartRange = SUBSTRING(@range, CHARINDEX('/', @range, 0) + 1, CHARINDEX('-', @range, 0) - CHARINDEX('/', @range, 0) - 1), 
     @EndRange = SUBSTRING(@range, CHARINDEX('-', @range, 0) + 1, LEN(@range)) 

    WHILE @StartRange <= @EndRange BEGIN 
     INSERT INTO @RangeTable (RangeNumber) VALUES (@StartRange) 
     SET @StartRange = @StartRange + 1 
    END 

    RETURN 
END 
GO 

А затем присоединиться к этому в ваш выбор для вашей исходной таблицы

SELECT * FROM OrderItemTable 
CROSS APPLY dbo.GetRange(OrderItem) 

Возможно, вы можете изменить функцию GetRange для обработки некоторых из ваших других ситуаций (+, без диапазона и т. Д.).

Смежные вопросы