Ссылки, которые я опубликовал в моих комментариях к вопросу, очень хорошо объясняют проблему. Я обобщил свои чувства по поводу того, почему проблема сохраняется, ниже:
php mysql query
, первая страница появится на странице mysql_query
, на которой есть пример, который отображает интерполяцию экранированного пользовательского ввода в запрос. Нет никакого упоминания (по крайней мере, не того, что я могу видеть) вместо использования подготовленных инструкций. Как говорили другие, существует так много учебных пособий, которые используют интерполяцию параметров, что не удивительно, как часто она все еще используется. Ответ на Ваш вопрос не, это не возможно к ссылочным именам корреляции, как Вы делаете. Полученная таблица производится Вашим внутренним запросом, прежде чем внешний запрос начнет оценивать соединения. Таким образом, имена корреляции как t
, tp
, и u
не доступны внутреннему запросу.
Для решения этого я рекомендовал бы использовать то же постоянное целочисленное значение во внутреннем запросе и затем присоединился бы к полученной таблице во внешнем запросе с помощью реального условия вместо 1=1
.
SELECT t.ticketid, u.userid, t.fullname, u.loginapi_userid, t.email,
tp.subject, tp.contents, a.PhoneNumber, a.Location, a.Extension,
a.BusinessUnit, a.Department
FROM swtickets t
INNER JOIN swticketposts tp ON (t.ticketid = tp.ticketid)
INNER JOIN swusers u ON (t.userid = u.userid)
LEFT OUTER JOIN (
SELECT cfv.typeid,
MIN(CASE cfv.customfieldid WHEN 1 THEN cfv.fieldvalue END) AS 'PhoneNumber',
MIN(CASE cfv.customfieldid WHEN 3 THEN cfv.fieldvalue END) AS 'Location',
MIN(CASE cfv.customfieldid WHEN 5 THEN cfv.fieldvalue END) AS 'Extension',
MIN(CASE cfv.customfieldid WHEN 8 THEN cfv.fieldvalue END) AS 'BusinessUnit',
MIN(CASE cfv.customfieldid WHEN 9 THEN cfv.fieldvalue END) AS 'Department'
FROM swcustomfieldvalues cfv
WHERE cfv.typeid = 2458
GROUP BY cfv.typeid
) AS a ON (a.typeid = t.ticketid)
WHERE t.ticketid = 2458;
Вы используете дизайн Значения атрибута объекта, и нет в конечном счете никакого способа сделать это масштабируемым, при попытке генерировать стандартные наборы результатов. Не пытайтесь сделать это в одном запросе.
Вместо этого запросите свои нормализованные таблицы сначала:
SELECT t.ticketid, u.userid, t.fullname, u.loginapi_userid, t.email,
tp.subject, tp.contents
FROM swtickets t
INNER JOIN swticketposts tp ON (t.ticketid = tp.ticketid)
INNER JOIN swusers u ON (t.userid = u.userid)
WHERE t.ticketid = 2458;
Затем запрашивают Ваши пользовательские поля, с результатом на нескольких строках набора результатов:
SELECT cfv.customfieldid, cfv.fieldvalue
FROM swcustomfieldvalues cfv
WHERE cfv.typeid = 2458;
Вы получите несколько строк в наборе результатов, одну строку для каждого пользовательского поля:
+---------------+--------------+
| customfieldid | fieldvalue |
+---------------+--------------+
| 1 | 415-555-1234 |
| 3 | Third office |
| 5 | 123 |
| 8 | Support |
| 9 | Engineering |
+---------------+--------------+
затем необходимо записать код приложения для отображения полей набора результатов на поля объекта приложения в цикле.
Используя таблицу Entity-Attribute-Value таким образом более масштабируемо и с точки зрения производительности и с точки зрения обслуживания кода.
Я записал бы это с несколькими соединениями. Когда Вы говорите, что это "возможно подверглось бы дополнительным издержкам", которые говорят мне, что Вы не протестировали его, чтобы быть уверенными. Если у Вас есть достойные индексы, соединения должны быть довольно тривиальными.
Это также показывает только, что одна из ловушек дженерика "содержит все" шаблон разработки таблицы.
Мое предложение было тем, что Вы исключили по причине эффективности. Например, не учитывая, где пункт и использование соединения (согласно t.ticketid = a.ticketid)
Вы смогли доказать свои мысли о неэффективности некоторыми конкретными примерами? Я знаю то, что Вы говорите, но безотносительно метода Вы используете каждую строку во внешнем запросе, соединяется с каждой строкой во внутреннем запросе так в зависимости от плана выполнения, это не может быть столь неэффективно, как Вы подозреваете?
Я предполагаю, что проблема 'cfv.typeid = t.ticketid' затем? Мои взгляды об этом состояли бы в том, что, в то время как MySQL поддерживает связанные подзапросы, что Вы пытаетесь сделать, кажется, что он мог перестать работать в соединении, потому что 'внутренний' запрос не является действительно 'внутренней' остальной частью запроса как он, находится в операторе Where. Но похоже, что Вы могли просто взять, где пункт из подзапроса и делает Ваше условие объединения на a.typeid = t.ticketid.