PHP + mySQL - получение общей позиции строки после запроса количества

0

Поэтому я пытаюсь отобразить отдельные ряды каждого продавца в своей панели на моем сайте на рынке. Для этого определенного ранга я подсчитываю, сколько последователей у каждого продавца, заказывая список в порядке убывания, а затем получая позицию каждого из них, чтобы они знали, где они занимают место. Я использую запрос, который работает, за исключением случаев, когда у двух продавцов одинаковое количество подписчиков, позиция меняется каждый раз. Это особенно назойливо, когда есть большое количество продавцов с таким же количеством последователей.

Запрос (в PHP):

<?php 
    $query = "SELECT rank
        FROM (
          SELECT vendor_id, followers, @rank:=@rank+1 AS rank
          FROM (
            SELECT vendor_id, COUNT(*) AS followers
            FROM $table
            GROUP BY vendor_id
            ORDER BY followers DESC
           ) as sq,
            (SELECT @rank:=0) AS tr
          ) as q WHERE vendor_id = $vendorId";
?>

где $vendorId= текущий идентификатор продавца.

Итак, опять же, главная проблема заключается в том, что если 10 продавцов, и у 7 из них есть 1 последователь. Каждый раз, когда продавец обновляется, они будут видеть рейтинг от 4 до 10. Я бы хотел, чтобы он просто сказал 4 для всех продавцов, у которых есть 1 последователь.

Обновление: Следующий запрос дал мне то, что я хотел, хотя я все же предпочел бы перенаправить рабочую нагрузку на PHP, чем хранить все это в MySQL.

<?php
    $connection->query("SET @curRank:=1, @prevRank:=0, @incRank=1;");

    $query = "SELECT rank
    FROM (
    SELECT vendor_id, followers,
      @curRank := IF(@prevRank = followers, @curRank, @incRank) AS rank,
      @incRank := @incRank + 1,
      @prevRank := followers
        FROM (
    SELECT vendor_id, COUNT(1) AS followers
    FROM $favTable
            GROUP BY vendor_id
    ORDER BY followers DESC, vendor_id DESC
        ) as sq,
        (SELECT @rank:=0) AS tr
     ) as q WHERE vendor_id = $vendorId";

    $result = $connection->fetchOne($query);
  • 0
    Храните подписчиков в переменной @oldfollowers , увеличивайте @rank , только если новые подписчики < @oldfollowers . Однако какое звание будет иметь число 11 с 0 подписчиками? 5 или 11? Или, если вы используете PHP: почему вы без необходимости усложняете ситуацию, форсируя это в MySQL, в то время как легко справиться с этим в PHP?
  • 0
    Кроме того: MYSQL 8 поддерживает rank () (именно это вы и искали), здесь можно увидеть некоторые обходные пути до этой версии.
Показать ещё 3 комментария
Теги:

2 ответа

0
Лучший ответ

Вы на правильном пути. Вам просто нужно добавить еще пару варов в запрос. Вы можете попробовать следующее:

<?php 
$query = "SELECT rank
    FROM (
      SELECT vendor_id, followers,
          @curRank := IF(@prevRank = followers, @curRank, @incRank) AS rank, 
          @incRank := @incRank + 1, 
          @prevRank := followers
      FROM (
        SELECT vendor_id, COUNT(*) AS followers
        FROM $table
        GROUP BY vendor_id
        ORDER BY followers DESC, vendor_id
       ) as sq,
        (SELECT @rank:=0) AS tr
      ) as q WHERE vendor_id = $vendorId";
?>

Пожалуйста, добавьте более конкретный порядок сортировки, как указано в @swa66, чтобы получить упорядоченные упорядоченные строки. Когда поле, используемое в сортировке, имеет одинаковые значения, mysql может возвращать строки на основе собственной логики упорядочения.

  • 0
    Проблема в том, что я не хочу, чтобы он сортировался по vendor_id , так как рейтинг также будет зависеть от их идентификатора; ранжирование пользователей с более низким или высоким идентификатором не будет честным рейтингом.
  • 0
    Он не ранжирует их по идентификатору. Если вы выполните этот SQL, вы увидите, что упорядочение по числу подписчиков. Когда число подписчиков одинаково для более чем одного поставщика, им всем присваивается один и тот же ранг. Идентификатор поставщика помогает поддерживать согласованность списка поставщиков с одинаковым рейтингом во время нескольких вызовов.
Показать ещё 3 комментария
-1

Чтобы получить согласованную позицию, все, что вам нужно сделать, это сделать ваш тип более конкретным, например, добавить также идентификатор в порядке, а не только последователей. Таким образом, вы получите последовательный результат.

Рядом с тем, чтобы получить наименьшее число, поскольку позиция в результирующем наборе с коллизиями не так уж и трудна: снова соберите ее также по идентификатору, который вы хотите получить, чтобы он был первым, чтобы выйти в вашем порядке.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню