3

人員の詳細が記載された表があります。個人の姓に基づいて、次/前のリンクを作成したいと考えています。人員はアルファベット順に追加されていないため、ID に基づいて次または前の行を選択することはできません。

これは非常に大きなテーブルです。関連するフィールドは id、name_l、および name_f です。個人の姓である name_l で注文したいと思います。

このタスクを達成するにはどうすればよいですか?

ありがとう!

編集 これは個人の詳細ページで使用されます。結果は、現在の行に基づいてデータベース内の次/前のエントリへのリンクを生成します (姓順)。たとえば、Joe Hammer を表示している場合、次のリンクは Frank Ingram にリンクします。

最終コード

ダニエルのおかげで、これが私が最終的に仕事をするようになったものです:

まず、インクリメントを 0 に設定します: $i = 0。次に、while ループでレコードをループしながら、これを 1 = $i++増やしました。次に、その特定のエントリの詳細ページへのリンクを作成しました。

<a href="details.php?id=<?php echo $member['id'];?>&amp;row=<?php echo $i;?>">Details</a>

[詳細] ページで、次の SQL を使用して次のレコードを選択しました。

$row = $_GET['row'];
$getNext = mysql_query("SELECT * FROM members ORDER BY name_l, id LIMIT ".$row.", 1");
$next = mysql_fetch_assoc($getNext);
$nextLink = $row + 1;

最後に、リンク:

<a href="member_details.php?id=<?php echo $next['id'];?>&amp;row=<?php echo $nextLink;?>"><?php echo $next['name_l'] . ", " . $next['name_f'];?></a>
4

2 に答える 2

9

まず、name_l列にインデックスが作成されていることを確認してください。ORDER BY次に、次のように the 句と theLIMIT句を簡単に使用できます。

SELECT * FROM personnel ORDER BY name_l, id LIMIT 0, 1;

LIMIT順序付きセット内の次のレコードを選択するには、句の値 0 をインクリメントするだけです。したがって、2 番目のレコード、3 番目のレコードなどを取得するために使用しLIMIT 1, 1ます。LIMIT 2, 1

インデックスを作成するには、次のコマンドname_lを使用できます。CREATE INDEX

CREATE INDEX ix_index_name ON personnel (name_l);

テストケース:

CREATE TABLE personnel (
   id int not null primary key, 
   name_l varchar(10), 
   name_f varchar(10)
);

CREATE INDEX ix_last_name_index ON personnel (name_l);

INSERT INTO personnel VALUES (1, 'Pacino', 'Al');
INSERT INTO personnel VALUES (2, 'Nicholson', 'Jack');
INSERT INTO personnel VALUES (3, 'De Niro', 'Robert');
INSERT INTO personnel VALUES (4, 'Newman', 'Paul');
INSERT INTO personnel VALUES (5, 'Duvall', 'Robert');

結果:

SELECT * FROM personnel ORDER BY name_l, id LIMIT 0, 1;
+----+---------+--------+
| id | name_l  | name_f |
+----+---------+--------+
|  3 | De Niro | Robert |
+----+---------+--------+
1 row in set (0.00 sec)

SELECT * FROM personnel ORDER BY name_l, id LIMIT 1, 1;
+----+--------+--------+
| id | name_l | name_f |
+----+--------+--------+
|  5 | Duvall | Robert |
+----+--------+--------+
1 row in set (0.00 sec)

SELECT * FROM personnel ORDER BY name_l, id LIMIT 2, 1;
+----+--------+--------+
| id | name_l | name_f |
+----+--------+--------+
|  4 | Newman | Paul   |
+----+--------+--------+
1 row in set (0.00 sec)

1回目の更新:(以下のコメントにさらに)

上記の例は、主に、最初のレコードを表示することから始めて、次のレコードに順番に移動し、次のレコードに移動し、1 つ戻るなどの場合に適しています。x ステップ前に x ステップ後ろに簡単に移動することもできますが、これは必須ではないようです。

ただし、ランダムなレコードから開始すると、上記のクエリを調整して次のレコードと前のレコードを取得するのが難しくなります。

この場合は、現在の位置のインデックス カウンターを保持するだけで済みます。で開始し$index = 0、 を使用して最初のレコードを表示し... LIMIT $index, 1ます。次に、1 ずつ増やして次を表示し、$index1 ずつ減らして前を表示します$index

一方、人事リストをレンダリングし、ユーザーが 1 つのレコードを (ランダムに) クリックする場合は、アプリケーション側 (php) の助けを借りてこれを機能させることもできます。次の順序付きリストをユーザーに表示するとします。

+----+-----------+--------+
| id | name_l    | name_f |
+----+-----------+--------+  // [Hidden info]
|  3 | De Niro   | Robert |  // Row 0 
|  5 | Duvall    | Robert |  // Row 1
|  4 | Newman    | Paul   |  // Row 2
|  2 | Nicholson | Jack   |  // Row 3
|  1 | Pacino    | Al     |  // Row 4
+----+-----------+--------+

ユーザーが Newman Paul をクリックした場合、row=2この従業員の詳細を表示するページにパラメーターを渡す必要があります。従業員の詳細を表示するページでは、Newman Paul が 3 行目にあることがわかります ( row=2)。したがって、前のレコードと次のレコードを取得するには、前のレコードと次のレコードの by をx変更LIMIT x, 1するだけです。row - 1row + 1

-- Previous 
SELECT * FROM personnel ORDER BY name_l, id LIMIT 1, 1;
+----+--------+--------+
| id | name_l | name_f |
+----+--------+--------+
|  5 | Duvall | Robert |
+----+--------+--------+
1 row in set (0.00 sec)


-- Next 
SELECT * FROM personnel ORDER BY name_l, id LIMIT 3, 1;
+----+-----------+--------+
| id | name_l    | name_f |
+----+-----------+--------+
|  2 | Nicholson | Jack   |
+----+-----------+--------+
1 row in set (0.00 sec)

2回目の更新:

次の MySQL 固有のクエリを使用して、ランダムな従業員の順序付きリスト内のレコード番号を取得できます。これを使用して、前後のレコードを取得できます。ただし、これはあまり効率的ではなく、何千ものレコードがある場合はパフォーマンスが低下する可能性があることに注意してください。

あなたが従業員のニコルソン・ジャックにいるとしましょう。

次のクエリを実行できます。

SELECT p.id, p.name_l, p.name_f, o.record_number
FROM   personnel p
JOIN   (
        SELECT    id,
                  @row := @row + 1 AS record_number
        FROM      personnel
        JOIN      (SELECT @row := -1) r
        ORDER BY  name_l, id
       ) o ON (o.id = p.id)
WHERE  p.name_l = 'Nicholson' AND p.name_f = 'Jack';

これはこれを返します:

+----+-----------+--------+---------------+
| id | name_l    | name_f | record_number |
+----+-----------+--------+---------------+
|  2 | Nicholson | Jack   |             3 |
+----+-----------+--------+---------------+
1 row in set (0.00 sec)

の代わりに、id がわかっている場合はWHERE句で使用できた可能性があることに注意してください。p.id = 2p.name_l = 'Nicholson' AND p.name_f = 'Jack'

record_numberこれで、この場合のフィールドを使用して3、この回答の最初の元のクエリを使用し、前と次のレコードを置き換えるだけで、前と次のレコードを取得できLIMIT 2, 1ますLIMIT 4, 1。どうぞ:

ニコルソン・ジャックの過去:

SELECT * FROM personnel ORDER BY name_l, id LIMIT 2, 1;
+----+--------+--------+
| id | name_l | name_f |
+----+--------+--------+
|  4 | Newman | Paul   |
+----+--------+--------+
1 row in set (0.00 sec)

次はニコルソン・ジャックから:

SELECT * FROM personnel ORDER BY name_l, id LIMIT 4, 1;
+----+--------+--------+
| id | name_l | name_f |
+----+--------+--------+
|  1 | Pacino | Al     |
+----+--------+--------+
1 row in set (0.00 sec)
于 2010-06-17T01:36:54.693 に答える
0

より良い SQL SELECT ステートメントを試してください。

SELECT * FROM tblPersonnel ORDER BY name_l ASC

詳細については、このリンクを試してください: http://w3schools.com/sql/sql_orderby.asp

于 2010-06-17T01:36:26.740 に答える