sql >> Databáze >  >> RDS >> Mysql

komplexní sql objednat podle

Odhaduji, že "id odpovědi" je 0 pro články a je to číslo článku pro komentáře. Pokud je to váš návrh, mělo by to fungovat:

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

PŘIDÁNO: Děkujeme za doplňující informace ve vašem komentáři. Uspořádat výsledky v požadovaném pořadí není tak snadné, protože prvním klíčem pro objednávání je datum vytvoření příspěvku pro zahájení vlákna. Toto není v datovém řádku, takže potřebujete spojení. Zde je můj nejlepší odhad založený na dodatečných informacích (které stále nejsou dostatečně úplné, aby mi zabránily hádat):

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;

Možná budete muset upravit syntaxi pro postgre. Testoval jsem to v SQL Server.

Pokud to stále nedělá to, co chcete, uveďte konkrétní způsob, jakým chcete data zpět. Nejlépe mi sdělte pořadí „id“, které bych měl pro data ve vašem souboru výpisu vidět, a také vysvětlit základ tohoto příkazu. Udělal jsem toto:

  1. Všechny zprávy ve vláknu (vlákno =zprávy a jejich komentáře) by měly být seskupeny.

  2. V rámci vlákna umístěte zprávu na začátek a za ní komentáře v obráceném chronologickém pořadí. Vlákno s posledním datem vytvoření/_datum by mělo být první, potom vlákno s druhým posledním datem vytvoření atd. (Vaše ukázková data obsahovala mnoho komentářů se stejným datem vytvoření, takže jsem použil "id" jako sekundární klíč objednávky pro komentáře v rámci vlákna.)

Poznámka: Váš výpis ukazuje, že datum created_date je aktualizováno na CURRENT_TIMESTAMP, pokud je příspěvek upraven. Pokud se jedná o živou nástěnku, mějte na paměti, že to může způsobit, že komentáře budou označeny datem před nadřazená zpráva, a to znamená, že vlákno zůstane nahoře, pokud je často upravováno (i bez skutečné změny jeho textu). (To není pro mé řešení relevantní, ale myslel jsem, že stojí za zmínku.)

Protože je vyžadováno spojení, bude tento dotaz nyní mnohem pomalejší. Můj návrh:udržujte dva sloupce data, „thread_last_modified“ a „item_last_modified“. Budete muset kaskádovat aktualizace ze spouštěčů vláken do komentářů, ale myslím, že to stojí za to, pokud není aktualizací mnoho, protože dotaz může být mnohem jednodušší. Netestoval jsem to, protože to vyžaduje několik změn ve vašem návrhu:

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;

PŘIDÁNO #2 :Pokud chcete pouze vlákno obsahující komentář s id ::thisOne, myslím, že můžete přidat tento řádek mezi klauzule ON a ORDER BY (pro mé první přidané řešení, spojení):

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

Teoreticky by toto vyhledávání mělo být pro dotaz vyhodnoceno pouze jednou, ale pokud to v praxi není, můžete jej předem vypočítat jako ::thisOneThreadID a přidat

where parentfeed.id = ::thisOneThreadID

Pro druhé řešení, za předpokladu, že provádíte předvýpočet znovu, zkuste

where coalesce(id,reply_id) = ::thisOneThreadID

Mimochodem, mám podezření, že obě moje řešení sloučí vlákna, která byla naposledy upravena přesně ve stejnou dobu...



  1. Prohoďte hodnoty dvou sloupců mezi dvěma tabulkami

  2. Jak mohu upravit velikost sloupce v tabulce MySQL?

  3. Postup MySQL v rámci výběru?

  4. Získávání chyby:Autentizace peer selhala pro uživatele postgres, když se pokouší zprovoznit pgsql s rails