Как назначить виртуальный ранг автоинкремента с лимитом 4? - PullRequest
0 голосов
/ 08 сентября 2011

Проще говоря, я хотел бы избавиться, чтобы заказать мой пид.

Вместо создания дополнительной таблицы под названием «ранг» с 4 строками, я хотел бы иметь возможность просто прикрепить виртуальный ранг, который дает тот же эффект.Мой ранг только для того, чтобы дать позицию моим тегам.Поскольку у меня есть 4 тега для каждого идентификатора, я буду иметь значение 1-4, перечисляя эти теги.

Таким образом, мне не придется вручную вводить одни и те же числа снова и снова.

Мои таблицы:

   people            tags_rel               tags           rank

id   | etc     id | pid  | tid | rid      id | tag          id
-----+-----    ---+------+-----+----      ---+--------      --
2345 |         1  | 2345 |  2  | 1        1  | bread        1
2346 |         2  | 2345 |  3  | 2        2  | water        2
2347 |         3  | 2345 |  1  | 3        3  | bear         3
               4  | 2345 |  6  | 4        4  | milk         4
               ---+------+-----+----      5  | hotdogs
               5  | 2346 |  3  | 1        
               6  | 2346 |  4  | 2
               7  | 2346 |  2  | 3
               8  | 2346 |  5  | 4
               ---+------+-----+----
               9  | 2347 |  6  | 1
              10  | 2347 |  1  | 2
              11  | 2347 |  4  | 3
              12  | 2347 |  5  | 4
               ---+------+-----+----

Мой запрос:

SELECT p.id as pid, t.tag as tname, tr.tid as trid, r.id as rank
FROM people AS p
RIGHT JOIN tags_rel AS tr ON tr.pid = p.id
LEFT JOIN tags AS t ON tr.tid = t.id
LEFT JOIN rank AS r ON tr.rid = r.id

MySQL ожидаемые результаты:

> +--------+------------+--------+------+
> | pid    | tname      |  trid  | rank |
> +--------+------------+--------+------+
> | 2345   | water      |    2   |   1  | 
> | 2345   | bread      |    1   |   2  |
> | 2345   | cereal     |    3   |   3  |
> | 2345   | milk       |    4   |   4  |
> | 2346   | cereal     |    3   |   1  |
> | 2346   | milk       |    4   |   2  |
> | 2346   | water      |    2   |   3  |
> | 2346   | hotdogs    |    5   |   4  |
> | 2347   | chocolate  |    6   |   1  | 
> | 2347   | bread      |    1   |   2  |
> | 2347   | bread      |    4   |   3  |
> | 2347   | bread      |    5   |   4  |
> +--------+------------+--------+------+

Я использую ранг в качестве позиции.Поэтому, какие бы теги не были прикреплены к pid, я бы хотел показать их по первой позиции.Поскольку теги различны для каждого pid, они будут иметь разные позиции.Я могу захотеть вызвать tname = water по rank = 1, и он отобразит все теги 'water' только в позиции 1.

Спасибо!

Ответы [ 3 ]

1 голос
/ 27 сентября 2011

Если я правильно понимаю, вы хотите удалить столбец rid из таблицы tag_rel и вместо этого иметь в своем запросе автоматически изменяемое поле позиции.«Положение» тега в вашем случае может пониматься как количество записей в таблице tag_rel, которые были добавлены для определенного pid.Другими словами: все записи в таблице с одинаковыми pid и id равными или меньшими, при условии, что id является полем автоинкремента.

Я думаю, что это можно сделать следующим образом.Имейте в виду, это может быть не самый эффективный код в мире:

SELECT id, pid, tid, (
    SELECT count(*) from tags_rel t2 where t2.pid = t1.pid and t2.id <= t1.id
) AS rid
FROM tags_rel t1;

Я не совсем уверен, что это будет работать, поскольку у меня есть только mysql 3, который не выполняет такие подзапросы, как этот,Хотя я думаю, что так и будет.

Если у вас может быть более 4 тегов, связанных с человеком, но вы хотите использовать только первые 4 тега для каждого человека, теперь вы можете использовать:

SELECT * FROM (
    [the above query]
) WHERE rid <= 4;
* 1017С учетом вышесказанного, я думаю, что почти во всех ситуациях вы могли бы просто order by pid, id и затем добавить ранговые числа в свой выходной носитель.Но тогда я не знаю твоего положения.

Я думаю, что самое важное: это то, что ты имел в виду?Если да, то, надеюсь, некоторые люди здесь смогут предоставить вам лучший ответ на ваш вопрос.

РЕДАКТИРОВАТЬ:

Для вашего текущего запроса это составит:

SELECT p.id as pid, t.tag as tname, tr.tid as trid, (
           SELECT count(*) 
           FROM tags_rel AS tr2 
           WHERE tr2.pid = tr.pid and tr2.id <= tr.id
       ) AS rank
FROM tags_rel AS tr
LEFT JOIN people AS p ON tr.pid = p.id
LEFT JOIN tags AS t ON tr.tid = t.id

при условии, что вам не нужна часть where rid <= 4.(Кстати: tr.tid as trid подсказывает, что вы хотите выбрать tags_rel.id вместо tags_rel.tid (== tags.id). Я не уверен, что вы это имеете в виду; если нет, то это может бытьлучше выбрать tr.tid as tid (или просто tr.tid).

1 голос
/ 08 сентября 2011

используйте порядок и ограничение

order by pid,rank
limit 4;
0 голосов
/ 23 сентября 2011

Вот запрос, который вы хотите.

SELECT p.id AS pid, t.tag AS tname,tr.tid AS trid,tr.rid AS rank
FROM 
people AS p JOIN tags_rel AS tr ON tr.pid = p.id
LEFT JOIN tags AS t ON tr.tid = t.id 
order by pid,rank;

Если вы просто хотите, чтобы теги 'water' находились в позиции 1, вы должны добавить "WHERE tname = 'water' AND rank = '1'" перед "ORDER BY".

Обратите внимание, что на самом деле нет необходимости в вашей таблице рангов. Если вы хотите, чтобы поле 'rid' было ограничено только 4 значениями, просто сделайте его типом enum.

...