如何分配虚拟自增等级限制为4?

发布于 2024-12-03 21:06:09 字数 2183 浏览 2 评论 0原文

简单地说,我想用rid来命令我的pid。

我希望能够附加一个具有相同效果的虚拟排名,而不是创建一个名为“rank”的 4 行额外表。我的排名只是为了给我的标签提供一个位置。由于每个 id 有 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 的标签都不同,因此它们的位置也不同。我可能想通过rank=1 来调用tname=water,它只会在位置1 中显示所有“水”标签。

谢谢!

Simply put, I would like rid to order my pid.

Instead of creating an extra table called 'rank' with 4 rows I would like to be able to just attach a virtual rank that gives the same effect. My rank is just there to give a position to my tags. Since I have 4 tags per id I would have a value of 1-4 enumerating those tags.

This way I won't have to manually put in the same numbers over and over again.

My tables:

   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
               ---+------+-----+----

My query:

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 expected results:

> +--------+------------+--------+------+
> | 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  |
> +--------+------------+--------+------+

I am using rank as position. So whatever tags are attached to pid I would like to show by first position. Since the tags are different for each pid they would have different positions. I may want to call tname=water by rank=1 and it would display all the 'water' tags in position 1 only.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

短暂陪伴 2024-12-10 21:06:09

如果我理解正确的话,您希望从 tag_rel 表中删除 rid 列,并在查询中使用自动生成的位置字段。在您的情况下,标签的“位置”可以理解为 tag_rel 表中为特定 pid 添加的条目数。换句话说:表中的所有条目都具有相同的 pidid 等于或更低,假设 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;

话虽如此,我认为在几乎所有情况下您也可以只 order通过 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 rod <= 4 部分。 (顺便说一下:tr.tid as trid 类型建议您选择 tags_rel.id 而不是 tags_rel.tid (= = tags.id)。我不确定这是否是您的意思;如果不是,最好选择 tr.tid 作为 tid (或者只是tr.tid)。)

If I understand it correctly, you want to remove the rid column from your tag_rel table, and have an automatically genarated position field in your query instead. The "position" of a tag in your case can be understood as the number of entries in the tag_rel table that have been added for a specific pid. In other words: all entries in the table with the same pid and an id that is equal or lower, assuming id is an autoincrement field.

I think this can be done as follows. Mind you, it may not be the most efficient code in the world:

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;

I'm not entirely sure this will work, as I only have mysql 3 here, which doesn't do subqueries like this. I think it will though.

If you may have more than 4 tags linked to a person, but you want only the first 4 tags for each person, you can now use:

SELECT * FROM (
    [the above query]
) WHERE rid <= 4;

This having been said, I think in almost all situations you might as well just order by pid, id and then adding the rank numbers in your output medium. But then, I don't know your situation.

I think the most important thing is: is this what you meant? If so, hopefully some people on here will be able to provide you with the best answer to your question.

EDIT:

For your current query, this would amount to:

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

assuming you don't need the where rid <= 4 part. (By the way: the tr.tid as trid kind of suggests you want to select tags_rel.id instead of the tags_rel.tid (== tags.id). I'm not sure if that's what you mean; if not, it might be better to select tr.tid as tid (or just tr.tid).)

俯瞰星空 2024-12-10 21:06:09

使用 order by 和 limit

order by pid,rank
limit 4;

make use of order by and limit

order by pid,rank
limit 4;
嘴硬脾气大 2024-12-10 21:06:09

这是您想要的查询。

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 中,则可以在“ORDER BY”之前添加“WHERE tname = 'water' AND rating = '1'”。

请注意,实际上不需要您的排名表。如果您希望“rid”字段仅限于 4 个值,只需将其设置为枚举数据类型即可。

Here is the query you want.

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;

If you just want the 'water' tags in position 1, you would add "WHERE tname = 'water' AND rank = '1'" before "ORDER BY".

Note that there is actually no need for your rank table. If you want the 'rid' field to be restricted to only 4 values, just make it an enum datatype.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文