2008-10-17 7 views
3

Je travaille sur un système de forums. J'essaie d'autoriser les utilisateurs à voir les posts qu'ils ont créés. Pour que ce lien fonctionne, je dois passer à la page sur le sujet particulier qu'ils ont posté dans qui contenait leur message, afin que les signets puissent fonctionner, etc. Puisqu'il s'agit d'une nouvelle fonctionnalité sur un ancien forum, Je voudrais le coder pour que le système de forum n'ait pas à garder trace de tous les messages, mais peut simplement remplir cette liste automatiquement.SQL - Trouver où dans une requête une certaine ligne sera

Je sais comment remplir la liste, mais je dois le faire:

Compte tenu d'une requête, où sera rangée X dans la requête (garantie unique par une combinaison d'identifiants) apparaissent? Comme dans, combien de lignes devrais-je compenser pour y arriver? Ce serait dans une requête triée.

Idéalement, je voudrais le faire avec SQL et non PHP, mais si cela ne peut pas être fait en SQL, je suppose que c'est aussi une réponse.^_^

Merci

Répondre

3

hmm cette solution fait quelques suppositions, mais je pense que cela devrait fonctionner pour ce que vous essayez de faire si je comprends bien:

SELECT count(post_id) FROM posts 
    WHERE thread_id = '{$thread_id}' AND date_posted <= '{$date_posted}' 

cela, vous obtiendrez le nombre de lignes dans un particulier thread (que je suppose que vous avez pré-calculé) qui sont égaux, ou plus tôt que la date affichée (le poste utilisateur en question). Sur la base de ces informations (disons le 15ème message de ce sujet), vous pouvez calculer à quelle page le résultat serait basé sur les valeurs de pagination des forums. à savoir

// dig around forum code for number of items per page 
$itemsPerPage = 10; // let's say 
$ourCount = getQueryResultFromAbove(); 

// this is the page that post will be on 
$page = ceil($ourCount/$itemsPerPage); 

// for example 
$link = '/thread.php?thread_id='.$thread_id.'&page='.$page; 
+0

J'aime ça parce qu'elle n'obtient pas toutes les lignes en une seule requête ... – Cervo

+0

Oohhh ... intelligent en effet. Merci! –

0

La chose au sujet des bases de données est qu'il n'y a pas de véritable « ordre » pour eux. Vous pouvez utiliser l'opérateur SCOPE_IDENTITY pour renvoyer l'ID unique de l'enregistrement inséré, puis écrire une sorte de fonction à paginer jusqu'à ce que cet enregistrement soit trouvé.

2

Si vous utilisez MSSQL, vous pouvez utiliser la fonction ROW_NUMBER() pour ajouter un numéro auto-incrémenté à chaque ligne d'une requête.

Je ne sais pas à quoi cela vous conviendrait. Mais il fera ce que vous avez demandé - assigner un nombre à la position d'une rangée dans le jeu de résultats d'une requête donnée.

Si cela est écrit en ph, vous utilisez probablement mySQL.

0

Expansion sur la suggestion de Troy, vous auriez besoin d'un sous-requête, essentiellement,

select row_number() OVER(ORDER BY MessageDate DESC) 
AS 'RowNum', * from MESSAGES 

puis mettre une sélection externe pour faire le travail réel:

select RowNum, Title, Body, Author from (
    select row_number() OVER(ORDER BY MessageDate DESC) 
    AS 'RowNum', * from MESSAGES) 
    where AuthorID = @User 

Utilisation Rownum pour calculer le numéro de page.

0

Je suis d'accord avec Troy, vous allez probablement autour de ce mal, de le réparer, nous devrions connaître plus de détails, mais en tout cas dans MySQL, vous pouvez le faire comme ça

SET @i=0; 
SELECT number FROM (SELECT *,@i:[email protected]+1 as number FROM Posts 
ORDER BY <order_clause>) as a WHERE <unique_condition_over_a> 

Dans PostgreSQL vous pourriez utiliser une séquence temporaire:

CREATE TEMPORARY SEQUENCE counter; 
SELECT number FROM (SELECT *,nextval('sequence') as number FROM Posts 
ORDER BY <order_clause>) as a WHERE <unique_condition_over_a> 
0

Je pense que vous voulez dire quelque chose comme ça (MySQL)?

START TRANSACTION; 

SET @rows_count = 0; 
SET @user_id = ...; 
SET @page_size = ...; 

SELECT 
    @rows_count := @rows_count + 1 AS RowNumber 
    ,CEIL(@rows_count/@page_size) AS PageNumber 
FROM ForumPost P 
WHERE 
    P.PosterId = @user_id; 

ROLLBACK; 
+0

Vous passez de @row_number à @row_count, mais en ignorant cela, ne serait-il pas plus facile d'initialiser @row_count à 0, et d'ignorer l'IFNULL? –

+0

Oui, vous avez raison. mais pour ma défense; J'étais trop bas sur la caféine quand j'ai écrit ceci. – Kris

0

La plupart des plates-formes SQL ont une extension exclusive de colonnes d'identité ou des séquences qui incrémente avec chaque élément dans un tableau. La plupart ont aussi des tables temporaires.

CREATE TABLE OF QUERY RESULTS WITH IDENTITY COLUMN 

INSERT INTO TABLE 
QUERY 
ORDER BY something 

puis la colonne d'identité est le nombre dans la requête et il vous indique combien d'entrées sont avant/après.

L'important est de commander par quelque chose. Sinon, vous pouvez obtenir des ordres différents avec chaque requête, auquel cas votre numéro ne veut rien dire ...

Questions connexes