sudhakarthikeyan Ответов: 3

Как разделить значение одного столбца в SQL server


INTIMEOutime

2016-04-05 10.00 2016-04-05 8.00

из вышеприведенного столбца я хочу разделить значение intime и out time отдельно

я хочу, чтобы результат был следующим

2016-04-05 10.03 Интайм

2016-04-05 8.00 Outtime


для этого как это сделать в sql server

Что я уже пробовал:

INTIMEOutime

2016-04-05 10.00 2016-04-05 8.00

из вышеприведенного столбца я хочу разделить значение intime и out time отдельно

я хочу, чтобы результат был следующим

2016-04-05 10.03 Интайм

2016-04-05 8.00 Outtime


для этого как это сделать в sql server

3 Ответов

Рейтинг:
2

Bryian Tan

Если вы используете SQL 2012, вы также можете поэкспериментировать с ним, используя функцию PARSENAME, вот пример:

DECLARE @INTIMEOutime TABLE (Id INT IDENTITY(1,1), SomeDateTime VARCHAR(50))

INSERT INTO @INTIMEOutime
	SELECT '2016-04-05 10.00 2016-04-05 8.00' UNION 
	SELECT '2016-04-05 9.45 2016-05-05 12.10' 

--SELECT REPLACE(REPLACE(@dummy,'.','|'),' ','.')

 SELECT Id,
 REPLACE(
	PARSENAME(REPLACE(REPLACE(SomeDateTime,'.','|'),' ','.'),2) + ' ' + PARSENAME(REPLACE(REPLACE(SomeDateTime,'.','|'),' ','.'),1),
	'|','.') 'OutTime',
 REPLACE(
	PARSENAME(REPLACE(REPLACE(SomeDateTime,'.','|'),' ','.'),4) + ' ' +  PARSENAME(REPLACE(REPLACE(SomeDateTime,'.','|'),' ','.'),3),
	'|','.') 'InTime'
FROM @INTIMEOutime


Или используйте метод value() XML, вот пример:

DECLARE @INTIMEOutime TABLE(Id INT IDENTITY,SomeDateTime VARCHAR(8000));
INSERT INTO @INTIMEOutime(SomeDateTime)VALUES('2016-04-05 10.00 2016-04-05 8.00');
INSERT INTO @INTIMEOutime(SomeDateTime)VALUES('2016-04-05 9.45 2016-05-05 12.10');

SELECT
    Id,
    InTime=n.v.value('/e[1]','VARCHAR(16)') + ' ' + n.v.value('/e[2]','VARCHAR(16)'),
     OutTime=n.v.value('/e[3]','VARCHAR(16)') + ' ' + n.v.value('/e[4]','VARCHAR(16)')
FROM
    @INTIMEOutime
    CROSS APPLY (
        SELECT 
            CAST('<e>'+REPLACE(SomeDateTime,' ','</e><e>')+'</e>' AS XML) AS itm
    ) AS i
    CROSS APPLY i.itm.nodes('/') AS n(v);


Оба они будут выводить:
Id	InTime	                OutTime
1	2016-04-05 10.00	2016-04-05 8.00
2	2016-04-05 9.45	        2016-05-05 12.10


Помощник SQL Server - Совет дня[^]

sql - разбиение столбца с разделителем на несколько столбцов - переполнение стека[^]


Рейтинг:
13

Wendelius

Если я правильно понял вопрос, вы хотите иметь значения в отдельных строках.

Для разделения значений существует довольно много способов сделать это, некоторые из которых упоминались в предыдущих решениях. Если формат даты содержит ведущие нули для месяца и дня, то вы можете разделить данные на основе второго пробела.

В качестве примера рассмотрим следующие данные

CREATE TABle #TheTable (
   TheValue varchar(100)
);
INSERT INTO #TheTable VALUES ('2016-04-05 10.00 2016-04-05 8.00');
INSERT INTO #TheTable VALUES ('2016-04-06 11.00 2016-04-06 9.00');
INSERT INTO #TheTable VALUES ('2016-04-07 12.00 2016-04-07 10.00');

Теперь вы можете запросить данные с помощью следующего запроса
WITH SeparatedColumns AS  (
   SELECT ROW_NUMBER() OVER (ORDER BY a.TheValue) AS RowNo,
      SUBSTRING(a.TheValue, 1, CHARINDEX(' ', a.TheValue, 12)) AS StartCol,
      SUBSTRING(a.TheValue, CHARINDEX(' ', a.TheValue, 12), 999) AS EndCol
   FROM #TheTable a
)
SELECT b.RowNo,
       CONVERT(datetime, REPLACE(TRIM(b.StartCol), '.', ':'), 120),
       'In time'
FROM SeparatedColumns b
UNION ALL
SELECT b.RowNo,
       CONVERT(datetime, REPLACE(TRIM(b.EndCol), '.', ':'), 120),
       'Out time'
FROM SeparatedColumns b
ORDER BY 1, 2

В запросе CTE данные разбиваются на два столбца. Дополнительный столбец добавляется для того, чтобы увидеть, какие значения приходят из одной и той же строки. В противном случае вы не знали бы, какие даты следует обрабатывать вместе, если результирующий набор содержит несколько строк.

Во внешней части выражение объединения используется для выборки столбцов в отдельных строках. В конце концов данные упорядочиваются на основе исходного номера строки таким образом, чтобы строки из одних и тех же данных находились рядом друг с другом.

Таким образом, результат будет
RowNo (No column name)        (No column name)
----- -----------------------  -------------------
1     2016-04-05 08:00:00.000  Out time
1     2016-04-05 10:00:00.000  In time
2     2016-04-06 09:00:00.000  Out time
2     2016-04-06 11:00:00.000  In time
3     2016-04-07 10:00:00.000  Out time
3     2016-04-07 12:00:00.000  In time


Однако, если у вас есть возможность изменить схему, я бы предложил:
- Не храните два отдельных элемента данных в одном столбце. Используйте отдельные столбцы
- Не храните даты в Столбцах varchar, всегда используйте правильный тип данных.


CHill60

5 тебе за дельные советы в конце!

Wendelius

Большое спасибо!

Рейтинг:
0

RickZeeland

Вот простое решение: Разделенная строка в Sql server 2008[^]

Также смотрите раздел определяемая пользователем функция здесь: Определяемая пользователем функция SQL для анализа строки с разделителями[^]

Если у вас есть SQL Server 2016, вы можете использовать String_Split()


Maciej Los

;)