Вход • Регистрация

Как поправить SQL запрос

  • 22 января 2016 г. , редакция: 22 января 2016 г.
  • Доброго дня!

    В функции ниже формируется запрос к базе для вывода товаров:

    Код
    private function list_elements_query($time, $cat_ids)
    {
    switch($this->diafan->configmodules("sort"))
    {
    case 1:
    $order = 's.id DESC';
    break;
    case 2:
    $order = 's.id ASC';
    break;
    case 3:
    $order = 's.name'._LANG.' ASC';
    break;
    default:
    $order = 's.sort DESC, s.id DESC';
    }
    $rows = DB::query_range_fetch_all(
    "SELECT s.id, s.[name], s.timeedit, s.[anons], s.site_id, s.brand_id, s.no_buy, s.article,"
    ." s.hit, s.new, s.action, s.is_file FROM {shop} AS s"
    .($this->diafan->_route->sort == 1 || $this->diafan->_route->sort == 2 ?
    " LEFT JOIN {shop_price} AS pr ON pr.good_id=s.id AND pr.trash='0'"
    ." AND pr.date_start<=".time()." AND (pr.date_start=0 OR pr.date_finish>=".time().")"
    ." AND pr.currency_id=0"
    ." AND pr.role_id".($this->diafan->_users->role_id ? " IN (0,".$this->diafan->_users->role_id.")" : "=0")
    ." AND (pr.person='0'".($this->person_discount_ids ? " OR pr.discount_id IN(".implode(",", $this->person_discount_ids).")" : "").")"
    : '')
    .($this->sort_config['use_params_for_sort'] ? " LEFT JOIN {shop_param_element} AS sp ON sp.element_id=s.id AND sp.trash='0' AND sp.param_id=".$this->sort_config['param_ids'][$this->diafan->_route->sort] : '')
    .($this->diafan->configmodules('where_access_element') ? " LEFT JOIN {access} AS a ON a.element_id=s.id AND a.module_name='shop' AND a.element_type='element'" : "")
    .($cat_ids ? " INNER JOIN {shop_category_rel} AS r ON s.id=r.element_id" : '')
    ." WHERE s.[act]='1' AND s.trash='0' "
    .($cat_ids ? "AND r.cat_id IN (".implode(',', $cat_ids).")" : 'AND s.site_id='.$this->diafan->_site->id)
    .($this->diafan->configmodules('where_period_element') ? " AND s.date_start<=".$time." AND (s.date_finish=0 OR s.date_finish>=".$time.")" : '')
    .($this->diafan->_route->brand ? " AND s.brand_id=".$this->diafan->_route->brand : '')
    .($this->diafan->configmodules('where_access_element') ? " AND (s.access='0' OR s.access='1' AND a.role_id=".$this->diafan->_users->role_id.")" : '')
    ." GROUP BY s.id ORDER BY "
    .($this->diafan->_route->sort ? $this->sort_config['sort_directions'][$this->diafan->_route->sort].',' : '')
    ."s.no_buy ASC, ".$order,
    $this->diafan->_paginator->polog, $this->diafan->_paginator->nastr
    );
    return $rows;
    }


    Как поправить запрос, чтобы выдавались только те товары, у которых в таблице {shop_param_element} присутствовало значение value1=2?
  • 24 января 2016 г. , редакция: 24 января 2016 г.
  • Если напрямую в базу запрос сделать, то сортировка работает
    Код
    SELECT s.name1 FROM diafan_shop AS s LEFT JOIN diafan_shop_param_element AS sp ON sp.element_id=s.id WHERE sp.value1=2
    .
    В shop.model.php добавил следующее:
    Код
    .($this->sort_config['use_params_for_sort'] ? " LEFT JOIN {shop_param_element} AS sp ON sp.element_id=s.id AND sp.trash='0' AND sp.param_id=2 ".$this->sort_config['param_ids'][$this->diafan->_route->sort] : '') ." WHERE sp.value1 = '2' "
    .($this->diafan->configmodules('where_access_element') ? " LEFT JOIN {access} AS a ON a.element_id=s.id AND a.module_name='shop' AND a.element_type='element'" : "")
    Не работает...
    Что делаю не так, поправьте, пожалуйста
    • 24 января 2016 г.
    • При таком варианте у Вас ошибка в sql запросе будет.
      • 24 января 2016 г.
      • Все верно, ошибка. Как прописать, чтобы ее не было?
        • 25 января 2016 г.
        • Если не проверять ваш код
          Цитата

          private function list_elements_query($time, $cat_ids)
          {
          switch($this->diafan->configmodules("sort"))
          {
          case 1:
          $order = 's.id DESC';
          break;
          case 2:
          $order = 's.id ASC';
          break;



          case 3:
          $order = 's.name'._LANG.' ASC';
          break;
          default:
          $order = 's.sort DESC, s.id DESC';
          }
          $rows = DB::query_range_fetch_all(
          "SELECT s.id, s.[name], s.timeedit, s.[anons], s.site_id, s.brand_id, s.no_buy, s.article,"
          ." s.hit, s.new, s.action, s.is_file FROM {shop} AS s"
          .($this->diafan->_route->sort == 1 || $this->diafan->_route->sort == 2 ?
          " LEFT JOIN {shop_price} AS pr ON pr.good_id=s.id AND pr.trash='0'"
          ." AND pr.date_start<=".time()." AND (pr.date_start=0 OR pr.date_finish>=".time().")"
          ." AND pr.currency_id=0"
          ." AND pr.role_id".($this->diafan->_users->role_id ? " IN (0,".$this->diafan->_users->role_id.")" : "=0")
          ." AND (pr.person='0'".($this->person_discount_ids ? " OR pr.discount_id IN(".implode(",", $this->person_discount_ids).")" : "").")"
          : '')
          .($this->sort_config['use_params_for_sort'] ? " LEFT JOIN {shop_param_element} AS sp ON sp.element_id=s.id AND sp.trash='0' AND sp.param_id=".$this->sort_config['param_ids'][$this->diafan->_route->sort] : '')
          .($this->diafan->configmodules('where_access_element') ? " LEFT JOIN {access} AS a ON a.element_id=s.id AND a.module_name='shop' AND a.element_type='element'" : "")
          .($cat_ids ? " INNER JOIN {shop_category_rel} AS r ON s.id=r.element_id" : '')
          ." WHERE s.[act]='1' AND s.trash='0' "
          .($cat_ids ? "AND r.cat_id IN (".implode(',', $cat_ids).")" : 'AND s.site_id='.$this->diafan->_site->id)
          .($this->diafan->configmodules('where_period_element') ? " AND s.date_start<=".$time." AND (s.date_finish=0 OR s.date_finish>=".$time.")" : '')
          .($this->diafan->_route->brand ? " AND s.brand_id=".$this->diafan->_route->brand : '')
          .($this->diafan->configmodules('where_access_element') ? " AND (s.access='0' OR s.access='1' AND a.role_id=".$this->diafan->_users->role_id.")" : '')
          ." GROUP BY s.id ORDER BY "
          .($this->diafan->_route->sort ? $this->sort_config['sort_directions'][$this->diafan->_route->sort].',' : '')
          ."s.no_buy ASC, ".$order,
          $this->diafan->_paginator->polog, $this->diafan->_paginator->nastr
          );
          return $rows;
          }

          То найдите в выше приведенном Вами коде строчку
          Код

          LEFT JOIN {shop_param_element} AS sp ON sp.element_id=s.id AND sp.trash='0' AND sp.param_id=".$this->sort_config['param_ids'][$this->diafan->_route->sort] : '')
          .($this->diafan->configmodules('where_access_element') ? " LEFT JOIN {access}

          И замените ее на эту строчку
          Код

          LEFT JOIN {shop_param_element} AS sp ON sp.element_id=s.id AND sp.trash='0' AND sp.param_id=".$this->sort_config['param_ids'][$this->diafan->_route->sort] : '')
          .($this->diafan->configmodules('where_access_element') ? " AND sp.value='1' LEFT JOIN {access}

          Теперь, в результате получим то, что вы хотели
          Цитата

          Как поправить запрос, чтобы выдавались только те товары, у которых в таблице {shop_param_element} присутствовало значение value1=2?
          • 25 января 2016 г. , редакция: 25 января 2016 г.
          • Вставил
            Код
            .($this->diafan->configmodules('where_access_element') ? " AND sp.value1='2' LEFT JOIN {access} AS a ON a.element_id=s.id AND a.module_name='shop' AND a.element_type='element'" : "")


            Никакого эффекта...У кого еще какие мысли по теме?
            • 25 января 2016 г. , редакция: 25 января 2016 г.
            • Алексей (yelrik), в самом начале Вы сказали
              Цитата
              у которых в таблице {shop_param_element} присутствовало значение value1=2?

              еще раз обращу Ваше внимание
              Цитата
              value1=2

              А потом говорите
              Цитата
              Никакого эффекта...У кого еще какие мысли по теме?

              Вот и не понять Вас, благо в ЛС Вы написали
              Цитата
              не помогло, все также выводит товар, у которого нет значения допхарактеристики с id=2

              еще раз обращу Ваше внимание
              Цитата
              допхарактеристики с id=2

              Теперь понятно. У Вас все смешалось в голове -> value === id.
              И так, если нужно id === 2, тогда вновь берем Ваш код
              Код

              private function list_elements_query($time, $cat_ids)
              {
              switch($this->diafan->configmodules("sort"))
              {
              case 1:
              $order = 's.id DESC';
              break;
              case 2:
              $order = 's.id ASC';
              break;



              case 3:
              $order = 's.name'._LANG.' ASC';
              break;
              default:
              $order = 's.sort DESC, s.id DESC';
              }
              $rows = DB::query_range_fetch_all(
              "SELECT s.id, s.[name], s.timeedit, s.[anons], s.site_id, s.brand_id, s.no_buy, s.article,"
              ." s.hit, s.new, s.action, s.is_file FROM {shop} AS s"
              .($this->diafan->_route->sort == 1 || $this->diafan->_route->sort == 2 ?
              " LEFT JOIN {shop_price} AS pr ON pr.good_id=s.id AND pr.trash='0'"
              ." AND pr.date_start<=".time()." AND (pr.date_start=0 OR pr.date_finish>=".time().")"
              ." AND pr.currency_id=0"
              ." AND pr.role_id".($this->diafan->_users->role_id ? " IN (0,".$this->diafan->_users->role_id.")" : "=0")
              ." AND (pr.person='0'".($this->person_discount_ids ? " OR pr.discount_id IN(".implode(",", $this->person_discount_ids).")" : "").")"
              : '')
              .($this->sort_config['use_params_for_sort'] ? " LEFT JOIN {shop_param_element} AS sp ON sp.element_id=s.id AND sp.trash='0' AND sp.param_id=".$this->sort_config['param_ids'][$this->diafan->_route->sort] : '')
              .($this->diafan->configmodules('where_access_element') ? " LEFT JOIN {access} AS a ON a.element_id=s.id AND a.module_name='shop' AND a.element_type='element'" : "")
              .($cat_ids ? " INNER JOIN {shop_category_rel} AS r ON s.id=r.element_id" : '')
              ." WHERE s.[act]='1' AND s.trash='0' "
              .($cat_ids ? "AND r.cat_id IN (".implode(',', $cat_ids).")" : 'AND s.site_id='.$this->diafan->_site->id)
              .($this->diafan->configmodules('where_period_element') ? " AND s.date_start<=".$time." AND (s.date_finish=0 OR s.date_finish>=".$time.")" : '')
              .($this->diafan->_route->brand ? " AND s.brand_id=".$this->diafan->_route->brand : '')
              .($this->diafan->configmodules('where_access_element') ? " AND (s.access='0' OR s.access='1' AND a.role_id=".$this->diafan->_users->role_id.")" : '')
              ." GROUP BY s.id ORDER BY "
              .($this->diafan->_route->sort ? $this->sort_config['sort_directions'][$this->diafan->_route->sort].',' : '')
              ."s.no_buy ASC, ".$order,
              $this->diafan->_paginator->polog, $this->diafan->_paginator->nastr
              );
              return $rows;
              }

              И в место строчки
              Код
              LEFT JOIN {shop_param_element} AS sp ON sp.element_id=s.id AND sp.trash='0' AND sp.param_id=".$this->sort_config['param_ids'][$this->diafan->_route->sort] : '')
              .($this->diafan->configmodules('where_access_element') ? " LEFT JOIN {access}

              Пишем так
              Код

              LEFT JOIN {shop_param_element} AS sp ON sp.element_id=s.id AND sp.trash='0' AND sp.param_id=".$this->sort_config['param_ids'][$this->diafan->_route->sort] : '')
              .($this->diafan->configmodules('where_access_element') ? " AND sp.param_id='2' LEFT JOIN {access}
              • 26 января 2016 г.
              • Вопрос поставлен абсолютно точно. Нужен фильтр именно по значению допхарактеристики. В таблице shop_param_element это именно поле value1. А про id=2 я написал потому как значения value1 это id из таблицы shop_param_select.
                И дело даже не в этом. Запрос с param_id тоже не работает.
                И еще...заметил интересную особенность. В shop.model.php в запросах касающихся таблицы shop_param_select почему то обращаются к полю value, но фактически в базе именно поле value1.

                Даешь brainstorm!
  • 26 января 2016 г.
  • Вот что выяснилось:

    1) В diafan 5.12.8 в таблице shop_param_element поле называлось value1, в diafan 6.0.7 - value. Из-за этого и возникла путаница.
    2) Включил профилирование запросов в админке.
    Код
    SELECT s.id, s.name1 AS name, s.timeedit, s.anons1 AS anons, s.site_id, s.brand_id, s.no_buy, s.article, s.hit, s.new, s.action, s.is_file FROM `diafan_shop` AS s
    ...
    INNER JOIN `diafan_shop_category_rel` AS r ON s.id=r.element_id WHERE s.act1='1' AND s.trash='0' AND r.cat_id IN (1) GROUP BY s.id ORDER


    Там где ... должен быть запрос:
    Код
    .($this->sort_config['use_params_for_sort'] ? " LEFT JOIN {shop_param_element} AS sp ON sp.element_id=s.id AND sp.trash='0' AND sp.param_id=".$this->sort_config['param_ids'][$this->diafan->_route->sort] : '')
    .($this->diafan->configmodules('where_access_element') ? " AND sp.value='2' LEFT JOIN {access} AS a ON a.element_id=s.id AND a.module_name='shop' AND a.element_type='element'" : "")

    НО его нет. Т.к. этот запрос выводится из тернарного оператора при TRUE, то его отсутствие означает, что условие не выполнено, поэтому выводится пустота.

    ВОПРОС: что проверяется условием и как сделать, чтобы оно выполнялось?
    • 26 января 2016 г.
    • Цитата
      ВОПРОС: что проверяется условием ... ?

      Данную переменную
      Код
      $this->sort_config['use_params_for_sort']
      я объяснил бы как метку, которая говорит о пользовательской сортировки.
      Цитата
      ВОПРОС: ... как сделать, чтобы оно выполнялось?

      В начале функции, перед формирование запроса присвойте данной переменно значение
      Код
      $this->sort_config['use_params_for_sort'] = true;

      Но на мой взгляд, это не решение вашей задачи (хоть результат будет), это реальный КОСТЫЛЬ.

Новости

  • 24 апреля, среда
  • В новой сборке совершили революцию в структурировании кастомизированной информации в шаблонах, добавили авторегистрацию пользователей, усовершенствовали защиту от спама, актуализировали накопительную скидку, а также улучшили производительность и стабильность работы системы.
  • 12 января
  • После выхода сборки 7.1 мы выпустили уже три патча, в каждом из которых улучшаем административную часть сайта. Сборка DIAFAN.CMS 7.1.3 уже доступна к установке. 
  • 15 декабря 2023 г.
  • Подводим итоги 2023 года. Выпустили новую сборку DIAFAN.CMS 7.1.1, вводим новые тарифы на аренду сайта и коммерческую поддержку и автообновления с января 2024 г., строим планы на будущий год.