Paweł Matejski pisze: Bartosz Derleta Aleksander Nabagło pisze:
Nie stawiaj wymagania "jednym zapytaniem"!
A z joinem potrafisz?
Zrobiłem narazie coś takiego:
SELECT /* Treść artykułu */ news_articles.id AS news_article_id, news_articles.hash AS news_article_hash, news_articles.title AS news_article_title, news_articles.summary AS news_article_summary, news_articles.content AS news_article_content, /* Ostatnia zmiana artykułu */ news_changes.user_id AS news_article_lastmod_user_id, auth_users.name AS news_article_lastmod_user_name, news_changes.datetime AS news_article_lastmod_datetime FROM news_articles, news_changes, auth_users WHERE news_changes.article_id = news_articles.id AND news_changes.user_id = auth_users.id ORDER BY news_changes.datetime DESC LIMIT 1
ale to wyciąga mi tylko ostatnią operację, i w ogóle mi się ten limit nie podoba (jak go nie ma, wyciąga wszystkie operacje, to jasne), a jak używam group by to wyciąga mi pierwszą operację - tak czy inaczej - to jest tylko proteza i to mocno badziewna. Chyba ten JOIN niewiele zmienia, ale kombinuję dalej - chyba, że ktoś w międzyczasie wspomoże lepszym rozwiązaniem.
Bartosz Derleta
Jakoś jak widzę zapytanie, nawet niedziałające, dużo łatwiej mi napisać takie, które (wydaje mi się) będzie poprawnie działać.
SELECT na.*, ncc.user_id as creat_user_id, nad.create_datetime, ncc.user_id as lastedit_user_id, nad.lastedit_datetime FROM news_articles na, news_changes ncc ( SELECT na1.id, max(case when operation = 1 then nc.datetime end) as create_datetime, max(case when operation = 2 then nc.datetime end) as lastedit_datetime, max(case when operation = 3 then nc.datetime end) as delete_datetime FROM news_article na1, news_changes nc WHERE na1.id = nc.artcle_id GROUP BY na1.id) as nad LEFT JOIN news_change nce ON (nad.id = nce.article_id and nad.lastedit_datetime = nce.datetime) WHERE na.id = nad.id AND nad.id = ncc.article_id AND nad.create_datetime = ncc.datetime
Dodanie części odpowiedzialnej za kasowanie oraz nazwy userów pozostawiam Tobie.
Problem ze skonstruowaniem złączenia
SELECT na.*, ncc.user_id as creat_user_id, nad.create_datetime,
Paweł Matejski pisze:
()
Potwór, ale działa :) Dzięki śliczne, jak przeanalizuję to któryś raz może w końcu dojdę do tego co jak działa ;]
Potwór, ale działa :)
Bartosz Derleta pisze:
Mam więc:
SELECT na.*, ncc.user_id as create_user_id, nad.create_datetime, aucreate.name as create_user_name, nce.user_id as lastedit_user_id, nad.lastedit_datetime, auchange.name as lastedit_user_name, ncee.user_id as delete_user_id, nad.delete_datetime, audelete.name as delete_user_name FROM news_articles na, news_changes ncc, ( SELECT na1.id, max(case when operation = 1 then nc.datetime end) as create_datetime, max(case when operation = 2 then nc.datetime end) as lastedit_datetime, max(case when operation = 3 then nc.datetime end) as delete_datetime FROM news_articles na1, news_changes nc WHERE na1.id = nc.article_id GROUP BY na1.id) as nad LEFT JOIN news_changes nccr ON (nad.id = nccr.article_id and nad.create_datetime = nccr.datetime) LEFT JOIN news_changes nce ON (nad.id = nce.article_id and nad.lastedit_datetime = nce.datetime) LEFT JOIN news_changes ncee ON (nad.id = nce.article_id and nad.delete_datetime = ncee.datetime) LEFT JOIN auth_users aucreate ON (aucreate.id = nccr.user_id) LEFT JOIN auth_users auchange ON (auchange.id = nce.user_id) LEFT JOIN auth_users audelete ON (audelete.id = ncee.user_id) WHERE na.id = nad.id AND nad.id = ncc.article_id AND nad.create_datetime = ncc.datetime
Czy da się tu coś skrócić, zoptymalizować? przyznam, że niezły koszmarek wyszedł. ;D
Bartosz Derleta pisze:
Potwór, ale działa :)
Mam więc:
SELECT na.*, ncc.user_id as create_user_id, nad.create_datetime, aucreate.name as create_user_name, nce.user_id as lastedit_user_id, nad.lastedit_datetime, auchange.name as lastedit_user_name, ncee.user_id as delete_user_id, nad.delete_datetime, audelete.name as delete_user_name FROM news_articles na, news_changes ncc, ( SELECT na1.id, max(case when operation = 1 then nc.datetime end) as create_datetime, max(case when operation = 2 then nc.datetime end) as lastedit_datetime, max(case when operation = 3 then nc.datetime end) as delete_datetime FROM news_articles na1, news_changes nc WHERE na1.id = nc.article_id GROUP BY na1.id) as nad LEFT JOIN news_changes nccr ON (nad.id = nccr.article_id and nad.create_datetime = nccr.datetime) LEFT JOIN news_changes nce ON (nad.id = nce.article_id and nad.lastedit_datetime = nce.datetime) LEFT JOIN news_changes ncee ON (nad.id = nce.article_id and nad.delete_datetime = ncee.datetime) LEFT JOIN auth_users aucreate ON (aucreate.id = nccr.user_id) LEFT JOIN auth_users auchange ON (auchange.id = nce.user_id) LEFT JOIN auth_users audelete ON (audelete.id = ncee.user_id) WHERE na.id = nad.id AND nad.id = ncc.article_id AND nad.create_datetime = ncc.datetime
Czy da się tu coś skrócić, zoptymalizować? przyznam, że niezły koszmarek wyszedł. ;D
!
Bartosz Derleta : E tam, jesli miesci sie na jednym ekranie to jest bardzo dobrze; chyba jeszcze nie widziales prawdziwych SQL-koszmarow :))
Ale wlasnie tedy droga -- jak napiszesz nieoptymalny koszmarek, wieloma, chcby malymi kroczkami go poprawisz, to po drodze zarowno wiele sie nauczysz, jak i zdobedziesz wiare w swoje mozliwosci przy nastepnym problemie.
I jeszcze jedno -- dopisz sobie komentarze, za pare dni lub tygodni nie bedziesz rozumial wlasnego kodu.