хочу разделить данные столбца SQL, как указано ниже - PullRequest
0 голосов
/ 03 октября 2018

У меня есть столбец coordinate, со многими координатами через запятую.Теперь я хочу разделить эти координаты.пример: если у меня есть координата, как

20.45847832-73.99704207,20.45868114-73.99712939,20.45849913-73.99750285,20.45831804-73.99736981,20.45848571-73.99702964,20.45851507-73.99715704,20.45852753-73.99720817,20.45849614-73.99728646,

, тогда я хочу только 1-ю координату, как

log:20.45847832 lat:73.99704207

Ответы [ 5 ]

0 голосов
/ 03 октября 2018

SQL Server поддерживает пространственные данные .Вы можете обработать эту строку как MULTIPOINT , проанализировать ее и вернуть первую точку в ней, например, с помощью:

declare @string nvarchar(200)='20.45847832-73.99704207,20.45868114-73.99712939,20.45849913-73.99750285,20.45831804-73.99736981,20.45848571-73.99702964,20.45851507-73.99715704,20.45852753-73.99720817,20.45849614-73.99728646'

declare @point geography=geography::Parse('MULTIPOINT (' + replace(@string,'-', ' ') +')')
                                   .STPointN(1)

select @point.Lat,@point.Long

'MULTIPOINT (' + replace(@string,'-', ' ') +')' заменяет - пробелом и создаетстрока, которая может быть проанализирована как многоточечный :

MULTIPOINT (20.45847832 73.99704207,20.45868114 73.99712939,20.45849913 73.99750285,20.45831804 73.99736981,20.45848571 73.99702964,20.45851507 73.99715704,20.45852753 73.99720817,20.45849614 73.99728646)

geography :: Parse может проанализировать хорошо известное текстовое представление пространственного объекта и вернутьСам объект как география объект.

После этого. STPointN (1) возвращает первую точку в многоточечной.Координаты доступны через свойства Lat и Long

ADO.NET поддерживает пространственные типы через библиотеку Microsoft.Sql.Types.geography объекты возвращаются как SqlGeography instance

0 голосов
/ 03 октября 2018

Извините за добавление третьего ответа, но это - опять же - совершенно новый подход.

Если вам нужна первая пара координат в формате, который вы указали в своем вопросе, это настоящий лайнер:

DECLARE @YourString VARCHAR(1000)='20.45847832-73.99704207,20.45868114-73.99712939,20.45849913-73.99750285,20.45831804-73.99736981,20.45848571-73.99702964,20.45851507-73.99715704,20.45852753-73.99720817,20.45849614-73.99728646,';

SELECT 'log:' + STUFF(LEFT(@YourString,PATINDEX('%,%',@YourString)-1),PATINDEX('%-%',@YourString),1,' lat:');

Результат

log:20.45847832 lat:73.99704207

ОБНОВЛЕНИЕ согласно вашим комментариям

Попробуйте это

DECLARE @mockupTable TABLE(tagdata VARCHAR(1000));
INSERT INTO @mockupTable VALUES('20.45847832-73.99704207,20.45868114-73.99712939,20.45849913-73.99750285,20.45831804-73.99736981,20.45848571-73.99702964,20.45851507-73.99715704,20.45852753-73.99720817,20.45849614-73.99728646,');

SELECT FirstPair
      ,LEFT(FirstPair,PATINDEX('%-%',FirstPair)-1) AS lon
      ,SUBSTRING(FirstPair,PATINDEX('%-%',FirstPair)+1,1000) AS lat
FROM @mockupTable t
CROSS APPLY(SELECT LEFT(tagdata,PATINDEX('%,%',tagdata)-1)) A(FirstPair);
0 голосов
/ 03 октября 2018

Если вы используете SQL Server 2016 и выше, вы можете использовать функцию STRING_SPLIT.Если я правильно понимаю, вы хотите получить только первую координату среди заданной координаты.Идея состоит в том, чтобы разделить на «,» затем подстроку его «-».После этого вы можете выбрать запись столько, сколько хотите.Надеюсь, что это ответ на ваш вопрос.

DECLARE @var VARCHAR(MAX) = '20.45847832-73.99704207,20.45868114-73.99712939,20.45849913-73.99750285,20.45831804-73.99736981,20.45848571-73.99702964,20.45851507-73.99715704,20.45852753-73.99720817,20.45849614-73.99728646,'

SELECT TOP 1 'Log:' + ColumnLog + ' Lat:' + ColumnLat AS Coordinate
FROM (
    SELECT
        SUBSTRING(VALUE, 1, CHARINDEX('-', VALUE)-1) AS ColumnLog,
        SUBSTRING(VALUE, CHARINDEX('-', VALUE) + 1, CHARINDEX('-', VALUE)-1) AS ColumnLat
    FROM STRING_SPLIT(@var, ',') WHERE RTRIM(VALUE) <> ''
) X
0 голосов
/ 03 октября 2018

Я добавляю это как новый ответ, поскольку он следует совершенно другому подходу: С SQL-Server-2016 + вы можете использовать JSON способности:

DECLARE @YourString VARCHAR(1000)='20.45847832-73.99704207,20.45868114-73.99712939,20.45849913-73.99750285,20.45831804-73.99736981,20.45848571-73.99702964,20.45851507-73.99715704,20.45852753-73.99720817,20.45849614-73.99728646,';

SELECT *
FROM OPENJSON('[{"lon":"' + REPLACE(REPLACE(@YourString,',','"},{"lon":"'),'-','","lat":"') + '"}]')
WITH(lon float '$.lon'
    ,lat float '$.lat');

Результат

lon         lat
20,45847832 73,99704207
20,45868114 73,99712939
20,45849913 73,99750285
20,45831804 73,99736981
20,45848571 73,99702964
20,45851507 73,99715704
20,45852753 73,99720817
20,45849614 73,99728646
0           NULL
0 голосов
/ 03 октября 2018

Подсказка: не храните такие значения в CSV-списке.Это ломает 1.NF и действительно плохой дизайн.Используйте этот код, чтобы восстановить ваш дизайн и сохранить эти координаты в соответствующей таблице.Попробуйте использовать GEOGRAPHY abilites , представленный в SQL-Server-2008.

Вы можете получить это за одно действие:

DECLARE @YourString VARCHAR(1000)='20.45847832-73.99704207,20.45868114-73.99712939,20.45849913-73.99750285,20.45831804-73.99736981,20.45848571-73.99702964,20.45851507-73.99715704,20.45852753-73.99720817,20.45849614-73.99728646,';

WITH Casted(AsXml) AS
(
    SELECT CAST('<x><y>' + REPLACE(REPLACE(@YourString,',','</y></x><x><y>'),'-','</y><y>') + '</y></x>' AS XML)
          .query('/x[y/text()]')
)
SELECT * FROM Casted;

Результат

<x>
  <y>20.45847832</y>
  <y>73.99704207</y>
</x>
<x>
  <y>20.45868114</y>
  <y>73.99712939</y>
</x>
<x>
  <y>20.45849913</y>
  <y>73.99750285</y>
</x>
<x>
  <y>20.45831804</y>
  <y>73.99736981</y>
</x>
<x>
  <y>20.45848571</y>
  <y>73.99702964</y>
</x>
<x>
  <y>20.45851507</y>
  <y>73.99715704</y>
</x>
<x>
  <y>20.45852753</y>
  <y>73.99720817</y>
</x>
<x>
  <y>20.45849614</y>
  <y>73.99728646</y>
</x>

Используйте это в XQuery/Xpath как здесь:

WITH Casted AS
(
    SELECT CAST('<x><y>' + REPLACE(REPLACE(@YourString,',','</y></x><x><y>'),'-','</y><y>') + '</y></x>' AS XML)
          .query('/x[y/text()]') AS AsXml
)
SELECT x.value('y[1]/text()[1]','decimal(12,8)') AS [log]
      ,x.value('y[2]/text()[1]','decimal(12,8)') AS [lat]
FROM Casted
CROSS APPLY AsXml.nodes('/x') A(x);

И вы получите

log         lat
20.45847832 73.99704207
20.45868114 73.99712939
20.45849913 73.99750285
20.45831804 73.99736981
20.45848571 73.99702964
20.45851507 73.99715704
20.45852753 73.99720817
20.45849614 73.99728646
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...