#mysql #perl #whmcs
#mysql #perl #whmcs
Вопрос:
Я пытался написать несколько небольших плагинов для личного использования с WHMCS. По сути, то, что я пытаюсь здесь сделать, это получить кучу информации об определенном порядке (ах) и вернуть ее в виде массива в Perl.
С Perl-битом у меня все в порядке, именно запрос MySQL, который я сформировал, вызывает у меня стресс..
Я знаю, что это большой и грязный, но то, что у меня есть, это:
SELECT tblhosting.id, tblhosting.userid, tblhosting.orderid, tblhosting.packageid, tblhosting.server, tblhosting.domain, tblhosting.username, tblorders.invoiceid, tblproducts.gid, tblservers.ipaddress, tblinvoices.status
FROM tblhosting, tblproducts, tblorders, tblinvoices, tblservers
WHERE tblorders.status = 'Pending'
AND tblproducts.gid = '2'
AND tblservers.id = tblhosting.server
AND tblorders.id = tblhosting.orderid
AND tblinvoices.id = tblorders.invoiceid
AND tblinvoices.status = 'Paid'
Я не знаю, должно ли это / работать /, но я предполагаю, что я на правильном пути, поскольку он возвращает то, что я ищу, однако он возвращает все дважды.
Например, я создал новую учетную запись в домене ‘sunshineee.info ‘, а затем в phpMyAdmin выполнил приведенный выше запрос.
id userid orderid packageid server domain username invoiceid gid ipaddress status
13 7 17 6 1 sunshineee.info sunshine 293 2 184.22.145.196 Paid
13 7 17 6 1 sunshineee.info sunshine 293 2 184.22.145.196 Paid
Кто-нибудь может подсказать мне, где я ошибся в этом.. Очевидно (возможно, недостаточно очевидно) Я хочу, чтобы за совпадение возвращалась только одна строка.. Я пробовал это с> 1 доменом в базе данных, и он вернул дубликаты для каждого из совпадений..
Любая помощь была бы высоко оценена 🙂
Ответ №1:
SELECT distinct tblhosting.id, tblhosting.userid, tblhosting.orderid, tblhosting.packageid, tblhosting.server, tblhosting.domain, tblhosting.username, tblorders.invoiceid, tblproducts.gid, tblservers.ipaddress, tblinvoices.status
FROM tblhosting, tblproducts, tblorders, tblinvoices, tblservers
WHERE tblorders.status = 'Pending'
AND tblproducts.gid = '2'
AND tblservers.id = tblhosting.server
AND tblorders.id = tblhosting.orderid
AND tblinvoices.id = tblorders.invoiceid
AND tblinvoices.status = 'Paid'
Комментарии:
1. Distinct решит (скроет) вашу непосредственную проблему, но вы должны попытаться выяснить, почему вы получаете повторяющиеся результаты. Вероятно, вам не хватает предложения where, которое объединяет две ваши таблицы… Смотрите ответ Нанне ниже.
2. Я бы настоятельно рекомендовал против этого, поскольку это скрывает основные проблемы
Ответ №2:
Ну, это почти невозможно без каких-либо определений таблиц, но вы делаете там много соединений. Вы начинаете с tblhosting.id и прокладываешь свой путь «наверх» оттуда. Если какая-либо из подключенных таблиц содержит двойную запись, вы получите больше обращений
Вы могли бы добавить DISTINCT
в свой запрос, но это не устранило бы основную проблему. Это может быть проблема с вашими данными: у вас есть 2 счета? Возможно, вам следует выбрать все ( SELECT * FROM
) и проверить, что возвращается, возможно, проверьте свои таблицы на наличие двойного содержимого.
Использование DISTINCT
в большинстве случаев не является хорошим выбором: это означает, что либо ваш запрос, либо ваши данные неверны (или вы не до конца их понимаете). Это может дать вам правильный результат на данный момент, но может вызвать проблемы позже.
Предположение о причине, по которой это происходит: Вы не подключаете таблицу products к цепочке идентификаторов. Итак, вы в основном добавляете ‘2’ к своему результату, насколько я могу видеть. Вы объединяетесь по продуктам, и единственное, что ограничивает эту таблицу, — это то, что «gid» должно быть 2. Итак, если вы добавите продукт с gid 2, вы получите другой результат. Либо присоединяйтесь к нему (возможно, tblproduct.orderid = tblorders.id ? просто догадываюсь здесь) или просто удалите его, поскольку он ничего не делает, насколько я могу видеть.
Если вы хотите сделать свой запрос немного понятнее, попробуйте неявно присоединиться, а сделать это следующим образом. Таким образом, вы действительно можете видеть, что происходит
SELECT tblhosting.id, tblhosting.userid, tblhosting.orderid, tblhosting.packageid, tblhosting.server, tblhosting.domain, tblhosting.username, tblorders.invoiceid, tblproducts.gid, tblservers.ipaddress, tblinvoices.status
FROM tblhosting
JOIN tblproducts ON /*you're missing something here!*/
JOIN tblorders ON tblorders.id = tblhosting.orderid
JOIN tblinvoices ON tblinvoices.id = tblorders.invoiceid
JOIN tblservers ON tblservers.id = tblhosting.server
WHERE
tblorders.status = 'Pending'
AND tblproducts.gid = '2'
AND tblinvoices.status = 'Paid'
Комментарии:
1. Я ценю предупреждение. Я убедился, что в базе данных нет повторяющихся или неправильных данных, поэтому я списываю это на свой неаккуратный запрос. Использование ‘DISTINCT’, похоже, действительно на данный момент устраняет проблему, однако я понимаю, что мне просто нужно будет найти другой способ обойти эту проблему.. Честно говоря, это всего лишь прототип, который я могу использовать, пока у меня не будет достаточно времени и базового кода, чтобы этот проект действительно заработал.. Я думаю, было бы намного лучше разобраться с этим сейчас, хотя, поскольку в будущем будет хуже, когда этот материал будет на производственном сервере.. Еще раз спасибо !! 🙂
2. Итак, что происходит, когда вы «выбираете *»?
3. При выборе *, похоже, возникает та же проблема с дубликатами.. Я не уверен в этом на 100%.. Возможно, мне просто придется разделить его на отдельные запросы.. Я знал, что был немного смелым, когда собирал все это воедино..
4. Проверьте мое дополнение. Посмотрите, что делает эта таблица продуктов
Ответ №3:
Я не вижу в вашем запросе JOIN to tblproducts
, похоже, это причина.
Комментарии:
1. Спасибо за это.. Я изменил запрос, чтобы включить, ГДЕ tblorders.status = ‘Ожидающий’ И tblproducts.id = tblhosting.packageid… И, похоже, ему это нравится 😉