0

簡単に言えば、pid を注文する必要はありません。

4行の「ランク」と呼ばれる追加のテーブルを作成する代わりに、同じ効果をもたらす仮想ランクをアタッチできるようにしたいと思います。私のランクは、私のタグに位置を与えるためのものです。ID ごとに 4 つのタグがあるため、これらのタグを列挙すると 1 ~ 4 の値になります。

これにより、同じ数字を何度も手動で入力する必要がなくなります。

私のテーブル:

   people tags_rel tags ランク

ID | 等ID | ピッド | tid | 削除 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 | シリアル | 3 | 3 |
> | 2345 | ミルク | 4 | 4 |
> | 2346 | シリアル | 3 | 1 |
> | 2346 | ミルク | 4 | 2 |
> | 2346 | 水 | 水 | 2 | 3 |
> | 2346 | ホットドッグ | 5 | 4 |
> | 2347 | チョコレート | 6 | 1 |
> | 2347 | パン | 1 | 2 |
> | 2347 | パン | 4 | 3 |
> | 2347 | パン | 5 | 4 |
> +--------+------------+--------+------+

ランクをポジションとして使用しています。したがって、pid にアタッチされているタグはすべて、最初の位置で表示したいと思います。タグは pid ごとに異なるため、位置が異なります。rank=1 で tname=water を呼び出すと、すべての「water」タグが位置 1 のみに表示されます。

ありがとう!

4

3 に答える 3

1

私が正しく理解している場合はrid、テーブルから列を削除し、tag_rel代わりにクエリで自動的に生成された位置フィールドを使用することをお勧めします。あなたの場合のタグの「位置」はtag_rel、特定の に追加されたテーブル内のエントリの数として理解できますpid。言い換えると、が自動インクリメント フィールドであると仮定して、同じpidおよびが等しいかそれ以下のテーブル内のすべてのエントリ。idid

これは次のようにできると思います。世界で最も効率的なコードではないかもしれません。

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しかなく、このようなサブクエリを実行しないため、これが機能するかどうかは完全にはわかりません。でもそうなると思います。

1 人の人物に 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.idtags_rel.tidtags.idtr.tid as tidtr.tid

于 2011-09-27T15:28:27.243 に答える
1

order by と limit を利用する

order by pid,rank
limit 4;
于 2011-09-08T02:42:30.400 に答える
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;

'water' タグだけを 1 位に配置したい場合は、「ORDER BY」の前に「WHERE tname = 'water' AND rank = '1'」を追加します。

ランクテーブルは実際には必要ないことに注意してください。「rid」フィールドを 4 つの値のみに制限する場合は、enum データ型にします。

于 2011-09-23T04:39:51.470 に答える