Перейти к содержимому

Sql как разбить запрос на части

  • автор:

Как разбить SQL запрос на составные части для дальнейшего использования в SQLiteDatabase?

Всем привет.
С JAVAй я знаком недавно и стандартные средства работы с SQL мне не понравились.
Я привык запрос писать «одной строкой». Но в классе SQLiteDatabase нельзя отправить сырой запрос, а нужно отдельно заполнять данными каждый метод (.update(), .query(), .insert() . ).
Пример:

INSERT INTO `tb_users` (`id`,`nick`) VALUES (234,'user_nuck');

Есть ли стандартные методы для разбора запроса, чтобы его в последующем использовать в .insert(String table, String nullColumnHack, ContentValues values) и т.п.? А то в ручную парсить побаиваюсь, мало ли, ошибусь где-нибудь ))

  • Вопрос задан более трёх лет назад
  • 546 просмотров

STRING_SPLIT (Transact-SQL)

STRING_SPLIT — это табличное значение функция, которая разбивает строку на строки подстроек на основе указанного символа разделителя.

Уровень совместимости 130

STRING_SPLIT требует, чтобы уровень совместимости был не менее 130. Если уровень меньше 130, ядро СУБД не удается найти функцию STRING_SPLIT .

Сведения об изменении уровня совместимости базы данных см. в статье Просмотр или изменение уровня совместимости базы данных.

Конфигурация совместимости не нужна STRING_SPLIT в Azure Synapse Analytics.

Синтаксис

STRING_SPLIT ( string , separator [ , enable_ordinal ] ) 

Аргументы

string

Выражение любого типа символа (например, nvarchar, varchar, nchar или char).

separator
enable_ordinal

Область применения: База данных SQL Azure, Управляемый экземпляр SQL Azure, Azure Synapse Analytics (только бессерверный пул SQL) и SQL Server 2022 (16.x) и более поздних версий

Выражениеint или bit, которое служит флагом для включения или отключения выходного столбца ordinal . Значение 1 включает ordinal столбец. Если enable_ordinal опущен NULL или имеет значение 0 , ordinal столбец отключен.

Типы возвращаемых данных

Если выходной ordinal столбец не включен, возвращает таблицу с одним столбцом, STRING_SPLIT строки которой являются подстроками. Имя столбца — value . Возвращает значение типа nvarchar, если любой из входных аргументов имеет тип nvarchar или nchar. В противном случае возвращается значение типа varchar. Длина типа возвращаемого значения равна длине аргумента string.

Если аргумент enable_ordinal передается значение 1 , возвращается второй столбец ordinal , состоящий из 1-х значений индексов позиции каждой подстроки в входной строке. Тип возвращаемого значения — bigint.

Замечания

STRING_SPLIT вводит строку с разделителями и вводит один символ для использования в качестве разделителя или разделителя. При необходимости функция поддерживает третий аргумент со значением 0 или отключает или 1 включает соответственно выходной ordinal столбец.

STRING_SPLIT выводит таблицу с одним столбцом или двойным столбцом в зависимости от аргумента enable_ordinal .

  • Если enable_ordinal , NULL опущен или имеет значение 0 , возвращает таблицу с одним столбцом, STRING_SPLIT строки которой содержат подстроки. Имя выходного столбца — value .
  • Если enable_ordinal имеет значение 1 , функция возвращает таблицу с двумя столбцами, включая ordinal столбец, состоящий из 1 значений индексов подстроок в исходной входной строке.

Аргумент enable_ordinal должен быть константным значением, а не столбцом или переменной. Он также должен быть битом или типом данных int со значением 0 или 1 . В противном случае функция вызывает ошибку.

Выходные строки могут быть расположены в любом порядке. Порядок не гарантирует соответствие порядка подстроек во входной строке. Можно переопределить окончательный ORDER BY порядок сортировки с помощью предложения инструкции SELECT , например ORDER BY value или ORDER BY ordinal .

0x0000 (char(0)) — это неопределенный символ в параметрах сортировки Windows и не может быть включен в STRING_SPLIT него.

Пустые строки нулевой длины присутствуют в том случае, если входная строка содержит два или несколько последовательных вхождений знака разделителя. Пустые подстроки обрабатываются так же, как и обычные подстроки. Вы можете отфильтровать все строки, содержащие пустую подстроку, с помощью WHERE предложения, например WHERE value <> » . Если входная строка имеет значение NULL , STRING_SPLIT функция с табличным значением возвращает пустую таблицу.

Например, в следующей SELECT инструкции в качестве разделителя используется символ пробела:

SELECT value FROM STRING_SPLIT('Lorem ipsum dolor sit amet.', ' '); 

При выполнении практики предыдущий SELECT возвращает следующую таблицу результатов:

значение
Lorem
ipsum
dolor
sit
amet.

Следующий пример включает ordinal столбец, передав 1 необязательный третий аргумент:

SELECT * FROM STRING_SPLIT('Lorem ipsum dolor sit amet.', ' ', 1); 

Затем эта инструкция возвращает следующую результирующую таблицу:

значение ordinal
Lorem 1
ipsum 2
dolor 3
sit 4
amet. 5

Примеры

А. Разделение строки значений с разделителями-запятыми

Следующая инструкция анализирует разделенный запятыми список значений и возвращает все непустые токены:

DECLARE @tags NVARCHAR(400) = 'clothing,road,,touring,bike' SELECT value FROM STRING_SPLIT(@tags, ',') WHERE RTRIM(value) <> ''; 

STRING_SPLIT возвращает пустую строку, если нет ничего между разделителем. Условие RTRIM(value) <> » удаляет пустые маркеры.

B. Разделение строки значений с разделителями-запятыми в столбце

Таблица Product содержит столбец с разделенным запятыми списком тегов, как показано в следующем примере:

ИД продукта Имя. Теги
1 Full-Finger Gloves clothing,road,touring,bike
2 LL Headset bike
3 HL Mountain Frame bike,mountain

Следующий запрос преобразовывает каждый список тегов и соединяет его с исходной строкой:

SELECT ProductId, Name, value FROM Product CROSS APPLY STRING_SPLIT(Tags, ','); 
ИД продукта Имя. Значение
1 Full-Finger Gloves clothing
1 Full-Finger Gloves road
1 Full-Finger Gloves touring
1 Full-Finger Gloves bike
2 LL Headset bike
3 HL Mountain Frame bike
3 HL Mountain Frame mountain

Порядок выходных данных может отличаться, так как порядок не гарантирует соответствие порядка подстроек во входной строке.

C. Объединение по значениям

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

SELECT value as tag, COUNT(*) AS [number_of_articles] FROM Product CROSS APPLY STRING_SPLIT(Tags, ',') GROUP BY value HAVING COUNT(*) > 2 ORDER BY COUNT(*) DESC; 

D. Поиск по значению тега

Разработчикам необходимо создать запросы для поиска статей по ключевым словам. Они могут использовать представленные ниже запросы.

Поиск продуктов с одним тегом (clothing):

SELECT ProductId, Name, Tags FROM Product WHERE 'clothing' IN (SELECT value FROM STRING_SPLIT(Tags, ',')); 

Поиск продуктов с двумя тегами (clothing и road):

SELECT ProductId, Name, Tags FROM Product WHERE EXISTS (SELECT * FROM STRING_SPLIT(Tags, ',') WHERE value IN ('clothing', 'road')); 

Д. Поиск строк по списку значений

Разработчикам необходимо создать запрос, который находит статьи по списку идентификаторов. Они могут использовать следующий запрос:

SELECT ProductId, Name, Tags FROM Product JOIN STRING_SPLIT('1,2,3',',') ON value = ProductId; 

Предыдущее STRING_SPLIT использование является заменой общего антипаттерна. Такой антипаттерн может включать создание динамической строки SQL на уровне приложения или в Transact-SQL. Или можно добиться антипаттерна с помощью LIKE оператора. См. следующую инструкцию: SELECT

SELECT ProductId, Name, Tags FROM Product WHERE ',1,2,3,' LIKE '%,' + CAST(ProductId AS VARCHAR(20)) + ',%'; 

F. Поиск строк по порядковым значениям

Следующая инструкция позволяет найти все строки с четным значением индекса:

SELECT * FROM STRING_SPLIT('Austin,Texas,Seattle,Washington,Denver,Colorado', ',', 1) WHERE ordinal % 2 = 0; 

Приведенная выше инструкция возвращает следующую таблицу:

значение ordinal
Техас 2
Вашингтон 4
Колорадо 6

G. Упорядочение строк по порядковым номерам

Следующая инструкция возвращает разделенные значения подстрок входной строки и их порядковые значения, упорядоченные столбцу ordinal :

SELECT * FROM STRING_SPLIT('E-D-C-B-A', '-', 1) ORDER BY ordinal DESC; 

Приведенная выше инструкция возвращает следующую таблицу:

значение ordinal
А 5
Б 4
О 3
D 2
E 1

Связанный контент

  • LEFT (Transact-SQL)
  • LTRIM (Transact-SQL)
  • RIGHT (Transact-SQL)
  • RTRIM (Transact-SQL)
  • SUBSTRING (Transact-SQL)
  • TRIM (Transact-SQL)
  • Строковые функции (Transact-SQL)

Обратная связь

Были ли сведения на этой странице полезными?

Обратная связь

Отправить и просмотреть отзыв по

Разбить выборку на сегменты определенной длины

Допустим, есть выборка из 99 записей и надо ее разбить на сегменты определенной длины, допустим 25. В выборке есть ключ. Пример стартовых данных: ID 1 2 3 4 5 После разбиение по 2 будет так: ID PAGE 1 1 2 1 3 2 4 2 5 3 Это легко делается через курсор. Однако, можно ли это сделать без курсора в MS SQL 2008 r2?

Отслеживать
задан 22 апр 2019 в 19:10
24.8k 12 12 золотых знаков 64 64 серебряных знака 163 163 бронзовых знака
ntile(50) over (order by id) ?
22 апр 2019 в 19:16
@teran, хм. Надо попробовать.
22 апр 2019 в 19:17
или какое нить dense_rank() over (order by rn/2) , где rn это номер строки?
22 апр 2019 в 19:19
@teran а что такое rn? Это результат другой оконной функции?
22 апр 2019 в 19:24
@iluxa1810 row_number
– user177221
22 апр 2019 в 19:26

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Дабы подытожить комментарии, возьмем тестовый пример данных из 100 последовательных номеров (предполагаем что они не такие уж и последовательные)

WITH dataset AS ( select 1 as id union all select id+1 from dataset where id < 100 ) select * from dataset; 

Далее из числа ранжирующих функций можем использовать ntile(N) , который делит выборку на N групп. То есть чтобы 100 строк разбить по 2, надо разделить на 50 групп. Для общего случая можно определить это число подзапросом:

SELECTid, ntile( (select count(id)/2 from dataset) ) over (order by id) FROM dataset; 
id ----------- -------------------- 1 1 2 1 3 2 4 2 5 3 6 3 7 4 

Либо второй вариант - использовать функцию dense_rank() , а для ранжирования взять номера строк, поделив их нацело на желаемое число элементов в группе:

. , nums AS ( SELECT id , (row_number() OVER (ORDER BY id) -1) AS rn FROM dataset ) SELECT id, dense_rank() OVER ( ORDER BY rn/2) FROM nums 

Sql как разбить запрос на части

1. Помните, что название темы должно хоть как-то отражать ее содержимое (не создавайте темы с заголовком ПОМОГИТЕ, HELP и т.д.). Злоупотребление заглавными буквами в заголовках тем ЗАПРЕЩЕНО.
2. При создании темы постарайтесь, как можно более точно описать проблему, а не ограничиваться общими понятиями и определениями.
3. Приводимые фрагменты исходного кода старайтесь выделять тегами code. /code
4. Помните, чем подробнее Вы опишете свою проблему, тем быстрее получите вразумительный совет
5. Запрещено поднимать неактуальные темы (ПРИМЕР: запрещено отвечать на вопрос из серии "срочно надо", заданный в 2003 году)
6. И не забывайте о кнопочках TRANSLIT и РУССКАЯ КЛАВИАТУРА, если не можете писать в русской раскладке

Модераторы: Akina, shadeofgray
'> SQL Script разбить на отдельные SQL запросы.

  • Подписаться на тему
  • Сообщить другу
  • Скачать/распечатать тему

Сообщ. #1 , 05.06.11, 08:38

Рейтинг (т): 53

Есть текстовый файл, суть его содержимого - SQL запросы к БД, различного типа (Select, Create Table, Insert, Create Procedure, Alter, . )
Вопрос: как можно из этого файла выудить каждый из запросов по отдельности.

Разбивать их по разделителю ; неполучиться, т к в Create Procedure и во многих других символ ; не является концом запроса. Тогда в таких случаях можео пробовать искать ключевое слово End с ; (но опять же нужно как то найти последний End, для такого запроса, поскольку внутри него может быть много промежуточных end`ов, закрывающих соответствующие условные, циклические и прочие операции)

Так опять же разделитель ; может встретиться в тексте запроса как символ критерия запроса.

В общем у меня четко сформулирвоанного алгоритма выделения запросов пока нет. Какие мысли есть у вас?

Сообщ. #2 , 05.06.11, 08:45
Рейтинг (т): 541
Цитата SPrograMMer @ 05.06.11, 08:38
Какие мысли есть у вас?

Изучите синтаксис полностью. затем выполняйте парсинг, начиная с "наиболее длинных" структур (которые не могут быть частью другой структуры).

Сообщ. #3 , 05.06.11, 18:37
Рейтинг (т): 135

Разбивать их по разделителю ; неполучиться, т к в Create Procedure и во многих других символ ; не является концом запроса.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *