sql >> Database teknologi >  >> RDS >> Mysql

kompleks sql rækkefølge efter

Jeg vil gætte på, at "svar-id" er 0 for artikler og er artikelnummeret for kommentarer. Hvis det er dit design, burde dette virke:

select * from yourTable
order by
  case when "reply id" = 0 then id else "reply id" end, id

TILFØJET: Tak for de yderligere oplysninger i din kommentar. At placere resultaterne i den rækkefølge, du ønsker, er ikke så let, fordi den første ordrenøgle er oprettet_datoen for trådstarterindlægget. Dette er ikke i datarækken, så du skal have et join. Her er mit bedste gæt baseret på de yderligere oplysninger (som stadig ikke er fuldstændige nok til at holde mig fra at gætte):

select
  f.id, f.user_id, f.type, f.reply_id, f.text, f.url, f.created_date,
  coalesce(parentfeed.created_date,f.created_date) as thread_date
from feed as f left outer join feed as parentfeed
on f.reply_id = parentfeed.id
order by
  thread_date desc,
  case when f.reply_id = 0 then 0 else 1 end,
  created_date desc, id;

Du skal muligvis justere syntaks for postgre. Jeg testede dette i SQL Server.

Hvis dette stadig ikke gør, hvad du ønsker, bedes du være specifik om, hvordan du vil have dataene tilbage. Fortæl mig helst den "id"-rækkefølge, jeg skal se for dataene i din dump-fil, og også forklare grundlaget for denne ordre. Her er, hvad jeg gjorde:

  1. Alle beskeder i en tråd (tråd =en besked og dens kommentarer) skal grupperes sammen.

  2. Inden for en tråd, læg beskeden øverst, efterfulgt af dens kommentarer i omvendt kronologisk rækkefølge. Tråden med den seneste oprettede/_dato skal være først, derefter tråden med den næstnyeste oprettede_dato og så videre. (Dine eksempeldata havde mange kommentarer med den samme oprettede_dato, så jeg brugte "id" som en sekundær rækkefølge for kommentarerne i en tråd.)

Bemærk: Dit dump angiver, at oprettet_dato er opdateret til CURRENT_TIMESTAMP, hvis et indlæg ændres. Hvis dette er en live opslagstavle, skal du være opmærksom på, at dette kan medføre, at kommentarer bliver dateret før forældremeddelelsen, og det betyder, at en tråd forbliver øverst, hvis den ofte ændres (selv uden egentlig ændring af teksten). (Det er ikke relevant for min løsning, men jeg syntes det var værd at bemærke.)

Fordi en joinforbindelse er påkrævet, vil denne forespørgsel nu være meget langsommere. Mit forslag:bevar to datokolonner, "tråd_sidst_modificeret" og "vare_sidst_modificeret". Du bliver nødt til at kaskadere opdateringer fra trådstartere til kommentarer, men jeg synes, det er det værd, hvis der ikke er mange opdateringer, fordi forespørgslen kan være meget enklere. Jeg har ikke testet dette, fordi det kræver flere ændringer af dit design:

select
  id, user_id, type, reply_id, text, url, thread_last_modified, item_last_modified
from feed
order by
  thread_last_modified desc,
  case when f.reply_id = 0 then 0 else 1 end,
  item_last_modified desc, id;

TILFØJET #2 :Hvis du kun vil have tråden, der indeholder kommentaren med id ::thisOne, tror jeg, du kan tilføje denne linje mellem ON og ORDER BY klausulerne (til min første tilføjede løsning, join):

where parentfeed.id = (
  select coalesce(reply_id,id)
  from feed
  where id = ::thisOne
)

I teorien skal dette opslag kun evalueres én gang for forespørgslen, men hvis det ikke er i praksis, kan du forudberegne det som ::thisOneThreadID og tilføje

where parentfeed.id = ::thisOneThreadID

For den anden løsning, forudsat at du forudberegner igen, prøv

where coalesce(id,reply_id) = ::thisOneThreadID

Jeg formoder i øvrigt, at begge mine løsninger vil flette tråde, der sidst blev ændret på nøjagtig samme tidspunkt...



  1. Tvetydig kolonnefejl i Laravel 4

  2. Hvordan kører man MySQL-kommando på bash?

  3. Problemer med at binde et imploderet array til en mysql-forberedt erklæring

  4. Vælg poster fra en uge tidligere i mysql