2013-06-28 4 views
0

У меня есть таблица (T-SQL) с 2 атрибутами - код и диапазон.T-SQL - множественные значения, разделенные запятыми, в одной строке

Code     Range 
-------------------- ---------- 
5000_RANGE   5001..5003 
5001     NULL 
5002     NULL 
5003     NULL 
5802     NULL 
5802_RANGE   5802..5804 
5803     NULL 
5804     NULL 
6401     NULL 

Я пытаюсь написать простой запрос для получения значений кода с «_RANGE» постфикса и значения кода (разделенные запятыми), заданный диапазон атрибутов на одной строке.

Code     Range 
-------------------- -------------- 
5000_RANGE   5001,5002,5003 
5802_RANGE   5802,5803,5804 

Какое оптимальное решение? Может быть, с помощью XML Path()?

+3

Это будет намного проще, если вы сделаете это в слое application/reporting вместо SQL. SQL не подходит для «создания» данных, которых нет. –

+0

С Powershell и я угадываю многие другие языки, вы можете сделать это без изменений, так как синтаксис 'X..X' автоматически расширяется. – JNK

ответ

1

Вы можете получить список с помощью автообъединение:

select range.code, c.code 
from (select code, range 
     from t 
     where code like '%RANGE' 
    ) range left outer join 
    (select t.* 
     from t 
     where code not like '%RANGE' 
    ) c 
    on c.code between left(range.range, 4) and right(range.range, 4) 

Получение их в разделителями отдельный список зависит от базы данных. Вот метод в MySQL:

select range.code, group_concat(c.code) 
from (select code, range 
     from t 
     where code like '%RANGE' 
    ) range left outer join 
    (select t.* 
     from t 
     where code not like '%RANGE' 
    ) c 
    on c.code between left(range.range, 4) and right(range.range, 4) 
group by range.code 
+0

Большое спасибо. Я буду использовать это решение. Это просто и функционально. – Rutz

-1

Что-то вроде

SELECT Code, Range FROM code_table WHERE Code LIKE "%_RANGE" 

Не уверен, представляя диапазон, как вам нравится.

0

Попробуйте это. Создание функции, как показано ниже:

ALTER FUNCTION GetRangeText 
(
    @Value VARCHAR(50) 
) RETURNS VARCHAR(100) 
AS 
BEGIN 
    DECLARE @Start AS INT 
    DECLARE @End AS INT 
    DECLARE @RangeText AS VARCHAR(200) 
    SET @RangeText = '' 

    SET @Start = CAST(SUBSTRING(@Value, 0, CHARINDEX('...', @Value)) AS INT) 
    SET @End = CAST(SUBSTRING(@Value, CHARINDEX('...', @Value) + 3, LEN(@Value)) AS INT) 

    WHILE @Start <= @End 
    BEGIN  
     SET @RangeText = @RangeText + CAST(@Start AS VARCHAR(100)) + ',' 

     SET @Start = @Start + 1 
    END 

    RETURN @RangeText 
END 

Потребляйте функцию в запросе SELECT, как показано ниже

SELECT Code, dbo.GetRangeText(Range) FROM Table1 WHERE Code LIKE '%_RANGE' 

Это даст освобожденная выход.

+0

Спасибо, что продемонстрировали мне одно из решений. – Rutz

0

Вы не указали, какую СУБД вы используете. Если вы используете MySQL, вы можете использовать такой запрос:

SELECT 
    Code, 
    GROUP_CONCAT(SUBSTRING_INDEX(rng, '..', 1)+numbers.digit) ranges 
FROM 
    (SELECT 0 digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL 
    SELECT 4 UNION ALL SELECT 4 UNION ALL SELECT 5) numbers 
    INNER JOIN 
    codes 
    ON SUBSTRING_INDEX(rng, '..', -1)-SUBSTRING_INDEX(rng, '..', 1)>=numbers.digit 
WHERE 
    rng like '%..%' 
GROUP BY 
    Code 

Это дает вам точный результат.

См. Скрипку here. Его можно улучшить для поддержки больших диапазонов.

+0

Благодарим вас за ввод и пример скрипки. Очень ценится. – Rutz