Хотите разделить данные столбца sql, как указано ниже

У меня есть столбец 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

Помещение нескольких значений в одну ячейку - это идея плохой, которая нарушает даже самое неудачное правило дизайна. Вероятно, вам следует сначала исправить дизайн и сохранить разные координаты в разных строках.

Panagiotis Kanavos 03.10.2018 09:29

Тем не менее, вы можете использовать STRING_SPLIT в SQL Server 2016 и более поздних версиях, чтобы разделить кулак на ,, а затем на -.

Panagiotis Kanavos 03.10.2018 09:30

Кстати, что это означает? SQL Server имеет пространственные типы и функции, включая возможность синтаксического анализа представлений WKT. Если это представляет собой MULTIPOINT или LINESTRING, вы можете использовать замену строк, чтобы превратить его, например, в MULTIPOINT ( 20.45847832 73.99704207,20.45868114 73.99712939), прежде чем разбирать его с помощью география :: Разбор

Panagiotis Kanavos 03.10.2018 09:33

Получить первую точку можно в однострочном geography::Parse('MULTIPOINT (' + replace(@string,'-', ' ') +')') .STPointN(1). После этого все зависит от того, как вы хотите использовать точку. ADO.NET поддерживает пространственные типы, поэтому вы можете вернуть его напрямую клиенту. Или вы можете использовать другие пространственные функции для расчета, например, расстояний

Panagiotis Kanavos 03.10.2018 11:42
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
4
209
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Подсказка: не храните такие значения в CSV-списке. Это ломает 1.NF и действительно плохой дизайн. Используйте этот код, чтобы исправить свой дизайн и сохранить эти координаты в связанной боковой таблице. Попробуйте использовать ГЕОГРАФИЯ 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

Если вы используете 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

Я голосую за это, так как принятый ответ очень близок к вашему, а ОП еще не имеет права голоса ... Вопрос был очень неясным ... Хороший ответ!

Shnugo 03.10.2018 10:54

Я добавляю это как новый ответ, поскольку он следует совершенно другому подходу: с 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
Ответ принят как подходящий

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

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

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);

У меня есть несколько строк для этого столбца. выберите координаты из tagdata, и после разделения он должен создать 2 столбца

Rahul Dhande Patil 03.10.2018 10:27

@RahulDhandePatil, просто добавьте FROM SomeTable и замените @YourString фактическим именем столбца.

Shnugo 03.10.2018 10:28

DECLARE @YourString VARCHAR (1000) = (выбрать координаты из данных тега); ВЫБРАТЬ 'журнал:' + STUFF (LEFT (координаты, PATINDEX ('%,%', координаты) -1), PATIND‌ EX ('% -%', координаты‌), 1, 'широта:');

Rahul Dhande Patil 03.10.2018 10:30

@RahulDhandePatil, извините, но это действительно важная информация, чтобы сообщить нам, откуда эта строка и как должен выглядеть вывод. Пожалуйста, не добавляйте такую ​​информацию в комментарии. Используйте опцию редактирования, чтобы повторно ввести свой вопрос и добавить его туда.

Shnugo 03.10.2018 10:32

это просто демонстрация, я делюсь не фактическими данными

Rahul Dhande Patil 03.10.2018 10:34

@RahulDhandePatil, но вы должны поделиться фактической структурой и, что наиболее важно, фактическим форматом вывода. Ваш журнал: 20.45847832 лат: 73.99704207 выглядит как строка в одну строку ...

Shnugo 03.10.2018 10:36

да. этот ответ, который вы дали, отлично подходит для одиноких. но для нескольких (для запроса выбора) он дает ошибку

Rahul Dhande Patil 03.10.2018 10:38

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)

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

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

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

Другие вопросы по теме