2009-04-24 5 views
2

Ich habe eine similar question vor und während die Antworten, die ich bekam, spektakulär waren, muss ich möglicherweise zu klären.Wählen Sie N Zeilen aus einer Tabelle mit einem nicht eindeutigen Fremdschlüssel

Genau wie This question Ich möchte N Anzahl der Zeilen abhängig von einem Wert in einer Spalte zurückgeben.

Mein Beispiel wird ich habe einen Blog, wo ich meine Beiträge zusammen mit einer Vorschau der Kommentare zeigen möchte. Die letzten drei Kommentare um genau zu sein.

Ich habe ich brauche für meine Beiträge, aber ich bin mein Gehirn, um die Kommentare richtig zu bekommen. Die Kommentartabelle hat einen Fremdschlüssel von post_id, der offensichtlich mehrere Kommentare an einen Beitrag anhängen kann. Wenn also ein Beitrag 20 Kommentare hat, möchte ich nur die letzten drei zurückgeben. Was das etwas schwierig macht, ist, dass ich es in einer Abfrage und nicht in einer "Limit 3" -Abfrage pro Blogpost machen möchte, was das Rendern einer Seite mit vielen Posts sehr fragwürdig macht.

SELECT * 
FROM replies 
GROUP BY post_id 
HAVING COUNT(post_id) <=3 

Diese Abfrage tut, was ich will, aber nur einen von jedem Kommentar und nicht drei zurückgibt.

Antwort

3
SELECT l.* 
FROM (
     SELECT post_id, 
       COALESCE(
       (
       SELECT id 
       FROM replies li 
       WHERE li.post_id = dlo.post_id 
       ORDER BY 
         li.post_id, li.id 
       LIMIT 2, 1 
       ), CAST(0xFFFFFFFF AS DECIMAL)) AS mid 
     FROM (
       SELECT DISTINCT post_id 
       FROM replies dl 
       ) dlo 
     ) lo, replies l 
WHERE l.replies >= lo.replies 
     AND l.replies <= lo.replies 
     AND l.id <= lo.mid 

Ein Index auf replies (post_id, id) (in dieser Reihenfolge) wird diese Abfrage erheblich verbessern.

Beachten Sie die Verwendung von l.replies >= lo.replies AND l.replies <= lo.replies: Dies dient dazu, den Index nutzbar zu machen.

Siehe den Artikel in meinem Blog für Details:

+0

danke für den Link deinen tollen Blog! –

+0

Gern geschehen :) – Quassnoi

+0

Ich werde definitiv etwas lesen müssen, um herauszufinden, was hier vor sich geht. Einige dieser Abfragen, insbesondere die CAST(), liegen außerhalb meines Geltungsbereiches. –

0

Verfolgen Sie das Kommentardatum? Sie können diese Ergebnisse sortieren, um nur die 3 neuesten zu erfassen.

+0

Das stimmt, aber ich müsste 3 der neuesten per post_id greifen. Wenn ich 15 Kommentare und 3 Beiträge habe, 5 Kommentare einen Beitrag, dann würde ich eine Abfrage wünschen, die 9 Kommentare zurückgeben würde. 3 der neuesten Kommentare für jede post_id. –

0

folgenden ian Jacobs Idee

declare (wie für jeden GROUPN Zeilen aus einer Tabelle auswählen) @PostID int

select top 3 post_id, comment 
from replies 
where [email protected] 
order by createdate desc 
Verwandte Themen