sql >> Databasteknik >  >> RDS >> Mysql

komplex sql ordning efter

Jag gissar att "svars-id" är 0 för artiklar och är artikelnumret för kommentarer. Om det är din design borde detta fungera:

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

LÄGG TILL: Tack för ytterligare information i din kommentar. Att placera resultaten i den ordning du vill ha är inte så lätt, eftersom den första beställningsnyckeln är create_date för trådstartsinlägget. Detta är inte i dataraden, så du behöver en join. Här är min bästa gissning baserat på den ytterligare informationen (som fortfarande inte är fullständig nog för att hålla mig från att gissa):

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 kan behöva justera syntaxen för postgre. Jag testade detta i SQL Server.

Om detta fortfarande inte gör som du vill, vänligen var specifik om hur du vill ha tillbaka data. Berätta helst vilken "id"-ordning jag ska se för data i din dumpfil, och även förklara grunden för den ordningen. Det här är vad jag gjorde:

  1. Alla meddelanden i en tråd (tråd =ett meddelande och dess kommentarer) bör grupperas tillsammans.

  2. Lägg meddelandet överst i en tråd, följt av kommentarerna i omvänd kronologisk ordning. Tråden med det senaste skapade/_datumet ska vara först, sedan tråden med det näst senaste skapade datumet och så vidare. (Din exempeldata hade många kommentarer med samma skapade_datum, så jag använde "id" som en sekundär ordningsnyckel för kommentarerna i en tråd.)

Obs! Din dump indikerar att create_date uppdateras till CURRENT_TIMESTAMP om ett inlägg ändras. Om detta är en live anslagstavla, var medveten om att detta kan leda till att kommentarer dateras före det överordnade meddelandet, och det betyder att en tråd kommer att hålla sig överst om den ändras ofta (även utan någon faktisk ändring av texten). (Det är inte relevant för min lösning, men jag tyckte det var värt att notera.)

Eftersom en anslutning krävs kommer denna fråga nu att gå mycket långsammare. Mitt förslag:behåll två datumkolumner, "thread_last_modified" och "item_last_modified". Du kommer att behöva kaskad uppdateringar från trådstartare till kommentarer, men jag tycker att det är värt det om det inte finns många uppdateringar, eftersom frågan kan vara mycket enklare. Jag har inte testat detta eftersom det kräver flera ändringar av din 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;

LÄGG TILL #2 :Om du bara vill ha tråden som innehåller kommentaren med id ::thisOne, tror jag att du kan lägga till den här raden mellan ON och ORDER BY klausulerna (för min första tillagda lösning, join):

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

I teorin bör denna uppslagning utvärderas bara en gång för frågan, men om det inte är i praktiken kan du förberäkna den som ::thisOneThreadID och lägga till

where parentfeed.id = ::thisOneThreadID

För den andra lösningen, förutsatt att du förberäknar igen, försök

where coalesce(id,reply_id) = ::thisOneThreadID

Förresten, jag misstänker att båda mina lösningar kommer att slå samman trådar som senast ändrades vid exakt samma tidpunkt...



  1. Spara HABTM med extra fält?

  2. Mappa anpassad JdbcTemplate-förfrågan i ett objekt

  3. Hur sorterar man MySQL-resultat med bokstäverna först, symbolerna sist?

  4. Entity Frameworks Entity Data Wizard kraschar vid anslutning till MySQL Database