MySQL Split String Функция SPLIT_STR не работает с LEFT JOIN.Любая проблема? - PullRequest
1 голос
/ 03 января 2012

Создание функции MySQL Split String SPLIT_STR fedecarg.com/.../mysql-split-string-function/

CREATE FUNCTION SPLIT_STR(
  x VARCHAR(255),
  delim VARCHAR(12),
  pos INT
)
RETURNS VARCHAR(255)
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
       LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1),
       delim, '');

Выполнить SQL:

SELECT t.en AS `type`, SPLIT_STR(l.en, ',', 1) AS city,
SPLIT_STR(l.en, ',', 2) AS country
FROM table1
JOIN table2
USING ( id )
LEFT JOIN table3 AS t ON table1.type = t.id
/* the next line has failure with SPLIT_STR */
LEFT JOIN table3 AS l ON table1.location = l.id
WHERE language.lang =  'en'
AND language.url =  'europe-countries'
LIMIT 1;

table1

id               | type            | location
-----------------+-----------------+-----------------
6BC45C02         | place           | london,england

table2

id               | url
-----------------+-----------------
6BC45C02         | europe-countries

Таблица3

id               | en
-----------------+-----------------
london           | London
england          | England

Неудачный результат:

type             | city            | country
-----------------+-----------------+----------------
place            | NULL            | NULL

Ожидаемый результат будет возвращать city и country:

type             | city            | country
-----------------+-----------------+-----------------
place            | London          | England

При проверке, работает ли SPLIT_STR с простым SQL:

SELECT SPLIT_STR(location, ',', 1) AS city, SPLIT_STR(location, ',', 2) AS contry
FROM table1
WHERE id =  '6BC45C02'
LIMIT 1;

возвращает прекрасный результат:

city             | contry
-----------------+-----------------
london           | england

Ответы [ 2 ]

1 голос
/ 03 января 2012

Из того, что я вижу, SPLIT_STR(l.en, ',', 1) всегда будет null (нечего разбивать на table3.en). Кроме того, условие соединения для таблицы table1.location = l.id всегда ложно для ваших данных (ни london, ни england равно london,england).

Исходя из желаемого результата, который вы опубликовали, я думаю, что вы ищете что-то вроде (я не уверен, что такое language.url = 'europe-countries', я не вижу в вопросе таблицу или псевдоним с именем "language", поэтомуЯ просто проигнорировал это)

SELECT t1.`type` AS `type`, 
MAX(CASE WHEN t3.id = SPLIT_STR(t1.location, ',', 1) THEN t3.en END) as `city`,
MAX(CASE WHEN t3.id = SPLIT_STR(t1.location, ',', 2) THEN t3.en END) as `country`
FROM table1 t1
INNER JOIN table2 t2 ON (t2.id = t1.id)
LEFT JOIN table3 t3 ON 
 (t3.id = SPLIT_STR(t1.location, ',', 1) OR t3.id = SPLIT_STR(t1.location, ',', 2))
GROUP BY t1.`type`

Обновлено (заменено l.en на t1.location)

1 голос
/ 03 января 2012

Может быть, это ... но производительность будет ужасной.

SELECT T1.type,
  SPLIT_STR(t.en, ',', 1) AS city,
  SPLIT_STR(l.en, ',', 2) AS country
FROM table1 t1
INNER JOIN table2 t2 
  ON T1.ID = T2.ID
LEFT JOIN table3 t 
  ON t.id = SPLIT_STR(t1.location, ',', 1)
LEFT JOIN table3 l 
  ON l.id = SPLIT_STR(t1.location, ',', 2)
WHERE t2.url = 'europe-countries'
LIMIT 1;

Это было бы лучше, так как для этого не требуется вызывать функцию 4 раза: (использовал coalesce, чтобы определить, работает ли функция, как ожидалось, вернет правильный регистр, затем строчные буквы, затем функцию прервет, если она не будет работать, как ожидалось )

SELECT InTable.Type, 
   coalesce(t.en, inTable.City, 'FunctionBroke') as city, 
   coalesce(l.en, intable.country, 'FunctionBroke2') as country
FROM 
    (SELECT t1.type,
      SPLIT_STR(T1.Location, ',', 1) AS City,
      SPLIT_STR(T1.Location, ',', 2) AS Country
    FROM table1 T1
    INNER JOIN table2 T2 
      ON T1.ID = T2.ID 
        AND t2.url='europe-countries'
    ) InTable
LEFT JOIN table3 t 
  ON InTable.City = t.id
LEFT join table3 l 
  ON InTable.Country = l.id
LIMIT 1;

Еще лучше существует: единственная цель таблицы 3 для правильного использования названия города / страны; и является ли единственной целью UDF (пользовательской функции) для разделения значений?

  • РЕДАКТИРОВАТЬ 1 Исправлена ​​первая должна была быть t.en вместо l.en на первый левый присоединиться.
  • EDIT 2 Fixed 2nd должен был быть t1 (это скопировать и вставить для вы)
  • РЕДАКТИРОВАТЬ 3 Пересмотрел все, в обоих ответах скопировал несколько ошибок в ОП
...