0

简单地说,我想摆脱订购我的 pid。

我不想创建一个名为“rank”的 4 行额外表,而是希望能够附加一个具有相同效果的虚拟排名。我的等级只是为了给我的标签一个位置。由于每个 id 有 4 个标签,因此枚举这些标签的值为 1-4。

这样我就不必一遍又一遍地手动输入相同的数字。

我的桌子:

   人 tags_rel 标签排名

编号 | 等id | 进程号 | 时间 | 摆脱ID | 标签编号
-----+----- ---+-----+-----+---- ---+-------- --
第2345章 1 | 第2345章 2 | 1 1 | 面包 1
第2346章 2 | 第2345章 3 | 2 2 | 水 2
第2347章 3 | 第2345章 1 | 3 3 | 承担 3
               4 | 第2345章 6 | 4 4 | 牛奶 4
               ---+--------+-----+---- 5 | 热狗
               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 预期结果:

> +--------+------------+--------+------+
> | 进程号 | 名称 | 三重奏 | 排名 |
> +--------+------------+--------+------+
> | 第2345章 水| 2 | 1 |
> | 第2345章 面包| 1 | 2 |
> | 第2345章 麦片| 高分辨率照片| CLIPARTO 3 | 3 |
> | 第2345章 牛奶| 4 | 4 |
> | 第2346章 麦片| 高分辨率照片| CLIPARTO 3 | 1 |
> | 第2346章 牛奶| 4 | 2 |
> | 第2346章 水| 2 | 3 |
> | 第2346章 热狗 | 5 | 4 |
> | 第2347章 巧克力| 高分辨率照片| CLIPARTO 6 | 1 |
> | 第2347章 面包| 1 | 2 |
> | 第2347章 面包| 4 | 3 |
> | 第2347章 面包| 5 | 4 |
> +--------+------------+--------+------+

我使用排名作为职位。因此,无论附加到 pid 的任何标签,我都想按第一个位置显示。由于每个 pid 的标签不同,因此它们的位置也不同。我可能想通过 rank=1 调用 tname=water ,它只会在位置 1 显示所有“水”标签。

谢谢!

4

3 回答 3

1

利用 order by 和 limit

order by pid,rank
limit 4;
于 2011-09-08T02:42:30.400 回答
1

如果我理解正确,您希望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;

话虽如此,我认为在几乎所有情况下,您最好只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)。)

于 2011-09-27T15:28:27.243 回答
0

这是您想要的查询。

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;

如果您只想要位置 1 中的“水”标签,您可以在“ORDER BY”之前添加“WHERE tname = 'water' AND rank = '1'”。

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

于 2011-09-23T04:39:51.470 回答