Как я могу выполнить запрос по идентификаторам в строке? - PullRequest
0 голосов
/ 01 октября 2010

У меня есть таблица A с этим столбцом:

  IDS(VARCHAR)
  1|56|23

Мне нужно выполнить этот запрос:

  select TEST from TEXTS where ID in ( select IDS from A where A.ID = xxx )

TEXTS.ID - это INTEGER. Как разделить строку A.IDS на несколько целых для объединения?

Должен работать на MySQL и Oracle. SQL99 предпочтительнее.

1 Ответ

6 голосов
/ 01 октября 2010

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

Сказав это, вы должны сделать следующее:

  1. Преобразовать число в строку
  2. Дополните его символом | (ваш разделитель), перед ним и после него (я расскажу вам почему ниже)
  3. Дополните текст, который вы просматриваете, тем же разделителем, до и после
  4. Сделайте LIKE на нем

Это будет работать медленно!

Вот SQL, который делает то, что вы хотите (предполагая, что все операторы и функции работают на вашем диалекте SQL, вы не говорите, что это за механизм базы данных):

SELECT
    TEXT   -- assuming this was misspelt?
FROM
    TEXTS  -- and this as well?
    JOIN A ON
        '|' + A.IDS + '|' LIKE '%|' + CONVERT(TEXTS.ID) + '|%'

Причина, по которой вам нужно добавить два с разделителем до и после, заключается в следующем: что, если вы ищете номер 5? Вы должны убедиться, что он не будет случайно соответствовать номеру 56 только потому, что он содержит цифру.

По сути, мы сделаем это:

... '|1|56|23|' LIKE '%|56|%'

Если в A когда-либо будет только 1 строка, она может работать быстрее, если вы сделаете это (но я не уверен, вам нужно измерить ее):

SELECT
    TEXT   -- assuming this was misspelt?
FROM
    TEXTS  -- and this as well?
WHERE
    (SELECT '|' + IDS + '|' FROM A) LIKE '%|' + CONVERT(TEXTS.ID) + '|%'

Если в вашей таблице TEXTS много строк, то стоит добавить код для генерации соответствующего SQL, сначала извлекая значения из таблицы A, создав соответствующий SQL с помощью IN и используйте это вместо:

SELECT
    TEXT   -- assuming this was misspelt?
FROM
    TEXTS  -- and this as well?
WHERE
    ID IN (1, 56, 23)

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

Если бы у вас был A.ID в качестве столбца, а значения в виде отдельных строк, вот как вы бы сделали запрос:

SELECT
    TEXT   -- assuming this was misspelt?
FROM
    TEXTS  -- and this as well?
    INNER JOIN A ON TEXTS.ID = A.ID

Это будет работать немного медленнее, чем предыдущий, но в предыдущем у вас есть издержки на необходимость сначала получить A.IDS, построить запрос и рискнуть создать новый план выполнения, который должен быть скомпилирован.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...