SQL-запрос возвращает поддельные повторяющиеся результаты?

#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… И, похоже, ему это нравится 😉