Подтвердить что ты не робот

MySQL - порядок по категориям_id пытается избежать дублирования рядом друг с другом

Пожалуйста, воздержитесь от моего английского языка.

У меня есть таблица, подобная этой,

 id |  category_id  |  product_id
 -----------------------------------
  1 |  1            |  1
  2 |  1            |  2
  3 |  2            |  1
  4 |  2            |  3
  5 |  1            |  4
  6 |  3            |  5

Я хочу, чтобы выход был,

id  |  category_id  |  product_id
----------------------------------
1   |  1            |  1
3   |  2            |  1
6   |  3            |  5
2   |  1            |  2
4   |  2            |  3
5   |  1            |  4

Короче, мне нужно, category_id нужно упорядочить так, чтобы он повторялся в цикле, например 1, 2, 3, 1, 2, 3,... и т.д.

4b9b3361

Ответ 1

Вот запрос, который дает вам этот результат:

SELECT p1.*
FROM `product` p1
JOIN `product` p2
      ON p2.category_id = p1.category_id 
      AND p2.id <= p1.id
GROUP BY p1.id
ORDER BY COUNT(*),category_id;

Где product - ваша таблица.

См. ДЕМО ЗДЕСЬ

Ответ 2

... старайтесь избегать дублирования рядом друг с другом

Хорошо, ладно. Самое простое решение, которое я могу придумать, - это GROUP BY 'product_id' ORDER BY 'category_id'. Это заставит вашу таблицу выглядеть так:

id  |  category_id  |  product_id
----------------------------------
1   |  1            |  1
3   |  2            |  1
2   |  1            |  2
4   |  2            |  3
5   |  1            |  4
6   |  3            |  5

Я предполагаю, что "category_id должен быть упорядочен так, чтобы он повторялся в циклах" - это перевод "Я не хочу дубликатов рядом друг с другом".

Если у вас было три категории на одном продукте и на продукте два, они объединялись бы вместе (1,1,1,2,2,2), но категории были бы численно упорядочены (1,2,3,1,2, 3). Это не идеальное решение для того, что вы хотите, но это простой, который, кажется, дает вам то, что вам нужно.

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

Ответ 3

Вот мое решение:

SET @rank=-1;
SET @prior_category=null;
SELECT @cycle_length:=COUNT(distinct category_id) FROM table1;

SELECT id, category_id, product_id 
FROM 
     (SELECT @rank:=CASE WHEN @prior_category!=category_id THEN 0 ELSE @rank+1 END AS rank, @prior_category:=category_id AS prior_category_id, id, category_id, product_id 
      FROM table1 
      ORDER BY category_id) AS extended_table1
ORDER BY rank*@cycle_length + category_id, id;

Демо здесь: http://sqlfiddle.com/#!9/5bce3/37

Ответ 4

//Get largest category_id value
$sql = "SELECT category_id FROM table ORDER BY category_id DESC LIMIT 1";
$result = $conn->query($sql);
$row = $result->fetch_assoc();
$maxCatId = $row['category_id'];

//Query for every possible category_id
$resultsArray = array();
for ($i = 1; $i <= $maxCatId; $i++) {
    $sql = "SELECT * FROM table WHERE category_id = " . $i;
    $resultsArray[] = $conn->query($sql);
}

//As long as $resultsArray is not empty
while ($resultsArray) {
    foreach ($resultsArray as $index => $res) {
        if ($row = $res->fetch_assoc()) {
            echo $row['id'] . ' ' . $row['category_id'] . ' ' . $row['product_id'];
        } else {
            unset($resultsArray[$index]);
        }
    }
}

Сначала получите наибольшее значение для category_id, затем выполните цикл от 1 до max category_id и сохраните все объекты результата в $resultsArray. Теперь вы можете использовать foreach через некоторое время для вывода результатов.

if else внутри foreach echos записывает или удаляет объект результата из $resultsArray, если в нем больше нет записей. Когда $resultsArray полностью пуст, а цикл прерывается.

Ответ 5

Вам действительно нужно подумать о реструктуризации своей таблицы, вам нужно добавить временное поле, которое будет классифицировать category_id, а затем упорядочить это поле remp. Мое предложение ниже.

CREATE TABLE Test1   (id int, t_category int, category_id int, Product_id int) ;

INSERT INTO Test1   (id, t_category, category_id, Product_id) ЗНАЧЕНИЯ   (1,1,1,1),       (2,2,1,2),       (3,1,2,1),       (4,2,2,3),   (5,3,1,4),   (6,1,3,5) ;

SELECT category_id, Код товара ИЗ Test1 упорядочить по t_category, category_id