Преобразуйте строку в список для логического сравнения в предложении Where

#sql #sql-server #where-clause

Вопрос:

Я работаю над инструкцией SQL в среде SQL Server Management Studio и столкнулся с проблемой. Я хочу взять таблицу, полную строк, которые являются списками, обозначенными буквой»,». Затем используйте NOT IN их для сравнения со списком значений. Это выглядело бы примерно так:

 commaStr = '6F, 0F, 0W'

Where (string is converted here) NOT IN ('0F', '0R', '0W') 
 

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

Комментарии:

1. Это строки, а не списки. IN не имеет смысла, потому что существует только одно строковое значение. Хранение данных таким образом в первую очередь является ошибкой проектирования, нарушающей самое основное правило проектирования базы данных. Вы можете использовать STRING_SPLIT для разделения строки на значения, но вы не сможете воспользоваться преимуществами индексов, поэтому запрос будет медленным. Реальное решение состоит в том, чтобы исправить ошибку в дизайне — либо используйте один столбец на флаг, либо используйте таблицу «многие ко многим».

2. @PanagiotisKanavos к сожалению, именно так решил поступить мой системный администратор. Мне было любопытно, было ли это вообще возможно.

3. Не имеет значения, что кто-то решил сделать. Не имеет значения, если кто-то заявляет, что Земля плоская. Это не. Это серьезная ошибка в дизайне, которая приведет к полному сканированию таблиц (и общим блокировкам на уровне таблиц), независимо от того, что вы попытаетесь. По STRING_SPLIT крайней мере, вы можете избежать плохих матчей. Запрос все равно заблокирует всю таблицу. Не обращайте внимания на мусор, хранящийся там — без реальных значений вы не сможете использовать ограничения или внешние ключи для обеспечения чистоты данных

4. Единственный способ заставить это работать-использовать базу данных с реальными индексированными массивами. Их очень мало, именно потому, что работа стола -хранить такие вещи. Не обращайте внимания на ограничения, убедитесь, что сохраненные значения имеют смысл и т. Д. Пока ошибка в дизайне не будет исправлена, вы можете попробовать FROM someTable CROSS APPLY STRING_SPLIT(csvField) as x WHERE x.value NOT IN ('0F', '0R', '0W')

5. Вероятно, было бы разумно использовать параметр с табличным значением или переменную таблицы. Но да, ваш текущий дизайн денормализован, вы должны это исправить. Какого рода соответствие вы на самом деле хотите: не должно быть точного совпадения двух таблиц? Или никакие совпадения из списка параметров не могут соответствовать столбцу таблицы? Какая-то другая логика?