Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Problem z mysql w SMF - INNER JOIN sub select
Forum PHP.pl > Forum > Bazy danych > MySQL
ktostaki
Witam
To moja pierwsza wiadomość na tym forum. Otóż urzęduję sobie na silniku forum SMF(Simple Machines Forum).
Zaszła konieczność pobrania tematów z określonego działu, przy czym potrzebuję również pobrać ostatni post z danego tematu więc skleciłem sobie takie zapytanie:

Kod
SELECT t.num_replies, m.subject, t.id_topic, m.id_msg FROM {db_prefix}topics AS t INNER JOIN(SELECT * FROM {db_prefix}messages ORDER BY id_msg DESC) AS m ON m.id_topic=t.id_topic WHERE
t.id_board=13 GROUP BY t.id_topic


O ile w mysql work bench zapytanie wykonuje się poprawnie i zwraca to co potrzebuje to już po wklejeniu do SMF w ten sposób:

Kod
$query = $smcFunc['db_query']('',''TUTAJ ZAPYTANIE DO BAZY);
oczywiście dalej również używam funkcji db smf.

pokazuje komunikat "Hacking attempt..". Myślę, że może to być wina sub SELECT'a w INNER JOIN. Proszę o pomoc, bo męczę się już z tym jakiś czas.
nospor
Cudne zabezpieczenia ma ten SMF, lol smile.gif

Czy tabela topics nie ma pola, w ktorym znajduje sie ID ostatniej wiadomosci?
Jesli nie, to wejdz do funkcji SMF, ktora wykonuje zapytanie i wywal to durne zabezpieczenie.

Albo zobacz jakiej funkcji ona uzywa, pewnie mysql_query, i odpal ją sam recznie zamiast tej funkcji SMF
ktostaki
Cytat(nospor @ 11.02.2014, 17:05:56 ) *
Cudne zabezpieczenia ma ten SMF, lol smile.gif

Czy tabela topics nie ma pola, w ktorym znajduje sie ID ostatniej wiadomosci?
Jesli nie, to wejdz do funkcji SMF, ktora wykonuje zapytanie i wywal to durne zabezpieczenie.

Albo zobacz jakiej funkcji ona uzywa, pewnie mysql_query, i odpal ją sam recznie zamiast tej funkcji SMF


Ok, każdy rekord tematu zawiera id ostatniej wiadomości, ale znacznika czasu owej już nie a potrzebuje tego by ustalić czy temat zawiera nieprzeczytane przez użytkownika posty.
nospor
Skoro jest ID ostatniej wiadomosci, to do selecta po topicach dodajesz poprostu LEFT JOIN i po sprawie. Zadne podzapytania ci tu nie sa potrzebne
ktostaki
Potrzebuję coś takiego:

Pobrać wszystkie rekordy z topics ale z warunkiem tylko jednej kategorii, następnie z tabeli wiadomości pobrać subject i do tego LEFT JOIN log_topics z tym, że musi to być LEFT JOIN bo INNER JOIN nie pokaże pustych a ja chcę mieć możliwość sprawdzenia poprzez np. $s['pole_z_tabeli_log_topics'] czy jest puste dla danego tematu, więc skleciłem coś takiego:

  1. SELECT t.id_topic AS topic_id,m.subject FROM {db_prefix}topics AS t, {db_prefix}messages AS m
  2. WHERE
  3. t.id_first_msg=m.id_msg




to działa, więc do tego potrzebuję dać

  1. LEFT JOIN {db_prefix}log_topics ON t.topic_id={db_prefix}log_topics.id_topic


Finalnie chciałbym otrzymać dane w takiej formie(żeby zwróciło tyle wierszy ile dopasuje tematów w tabeli topics):

t.topic_id | t.num_replies | m.subject | log_topics.id_msg

lub

t.topic_id | t.num_replies | m.subject | NULL


Pomóżcie, bo już próbowałem na wiele sposobów i cały czas pokazuje, że przy LEFT JOIN nieznana kolumna id_topic w tabeli topics.

ps przy edycji geshi się kaszani.

Proszę o pomoc.
nospor
1) Czemu t.topic_id ? W select pobierasz t.id_topic. Masz takie dwie kolumny?
2) Nie: {db_prefix}topics AS t, {db_prefix}messages AS m
a ({db_prefix}topics AS t, {db_prefix}messages AS m)
ktostaki
Cytat(nospor @ 12.02.2014, 12:51:26 ) *
1) Czemu t.topic_id ? W select pobierasz t.id_topic. Masz takie dwie kolumny?
2) Nie: {db_prefix}topics AS t, {db_prefix}messages AS m
a ({db_prefix}topics AS t, {db_prefix}messages AS m)


1. ponieważ w select id_topic z tabeli topics pobieram jako topic_id zeby roznoznic z topic_id z log_topics.

2. nie bardzo rozumiem to co napisałeś różni się tylko nawiasem, czy masz na mysli, że tylko jego brakuje?

// edit

Teraz

  1. SELECT t.id_topic AS topic_id,m.subject, l.id_msg FROM ({db_prefix}topics AS t, {db_prefix}messages AS m)
  2. LEFT JOIN {db_prefix}log_topics AS l ON l.id_topic=t.id_topic
  3. WHERE
  4. t.id_first_msg=m.id_msg AND
  5. t.id_board=13 AND
  6. t.num_replies>30


Wyrzuca mi bardzo duzo rekordow z kolei bez LEFT JOIN, jedynie kilkanascie i takiej ilosci potrzebuje z tym, ze z danymi z tabeli LEFT JOIN.
nospor
ad1) Ale w warunkach czy laczeniach uzywa sie nazw pol, a nie ich aliasow
ad2) Tak, czasami join nie widzi tabel, gdy jest wiecej niz 1 we FROM

Zas co do duzej ilosci rekordow to normalne. Skoro laczysz tabele, ktora ma duzo danych dla danego laczenia, to logiczne, ze to wszystko ci wypluje w postaci kolejnych rekordow
ktostaki
Cytat(nospor @ 12.02.2014, 13:11:21 ) *
ad1) Ale w warunkach czy laczeniach uzywa sie nazw pol, a nie ich aliasow
ad2) Tak, czasami join nie widzi tabel, gdy jest wiecej niz 1 we FROM

Zas co do duzej ilosci rekordow to normalne. Skoro laczysz tabele, ktora ma duzo danych dla danego laczenia, to logiczne, ze to wszystko ci wypluje w postaci kolejnych rekordow


Ok więc jak mogę osiągnąć coś takiego?

t.topic_id | t.num_replies | m.subject | log_topics.id_msg
t.topic_id | t.num_replies | m.subject | NULL
t.topic_id | t.num_replies | m.subject | log_topics.id_msg
t.topic_id | t.num_replies | m.subject | NULL
t.topic_id | t.num_replies | m.subject | NULL
t.topic_id | t.num_replies | m.subject | log_topics.id_msg

Chcialbym zeby rekordow bylo tyle ile dopasuje z tabeli topics a nie log_topics.
nospor
Ale co jest w tabeli log_topics i czemu chcesz pobrac tylko max 1 rekord z stamtad dla danego topicu, skoro widac, ze ta tabela dla danego topicu moze miec wiecej niz jeden rekord?
ktostaki
Cytat(nospor @ 12.02.2014, 13:18:30 ) *
Ale co jest w tabeli log_topics i czemu chcesz pobrac tylko max 1 rekord z stamtad dla danego topicu, skoro widac, ze ta tabela dla danego topicu moze miec wiecej niz jeden rekord?

Bo to się tyczy tylko do jednej kategorii forum i uzytkownika, bo tabela log_topics ma pola: id_topic, id_member, id_msg i zawiera informacje o ostatnio przeczytanym poscie i ta informacje potrzebuje nawet jezeli nie bedzie takiego rekordu wtedy dla rekordu danego tematu z (topics) ma zwrocic NULL i wiem ze user wtedy na pewno nie czytal tego tematu.
nospor
Kurcze.... no to wez lacz tę tabele po tych trzech polach id_topic, id_member, id_msg a nie ty łączysz tylko po jednym i sie dziwisz, ze massz milion rekordow
ktostaki
Cytat(nospor @ 12.02.2014, 13:28:02 ) *
Kurcze.... no to wez lacz tę tabele po tych trzech polach id_topic, id_member, id_msg a nie ty łączysz tylko po jednym i sie dziwisz, ze massz milion rekordow


Nie mogę, bo nie chcę pobrać tylko tych tematów które założył user ale wszystkie z okreslonego dzialu i finalnie chce zeby liczba rekordow była taka jak dopasowana w tabeli topics z tym, ze kazdy wiersz zawieral informacje z log_topics i to tyle. Nie mam glowy do tej logiki bazodanowej naprawde.
nospor
Cytat
Nie mogę, bo nie chcę pobrać tylko tych tematów które założył user ale wszystkie z okreslonego dzialu
A co ma piernik do wiatraka? JA ci mowie bys sprecywoal w JOIN wszystko....

Masz teraz
LEFT JOIN .... on raz
A masz miec
LEFT JOIN .... on (raz and dwa and trzy)

Gdzie raz, dwa i trzy to kolejne warunku laczace. I juz.
ktostaki
Cytat(nospor @ 12.02.2014, 13:53:56 ) *
A co ma piernik do wiatraka? JA ci mowie bys sprecywoal w JOIN wszystko....

Masz teraz
LEFT JOIN .... on raz
A masz miec
LEFT JOIN .... on (raz and dwa and trzy)

Gdzie raz, dwa i trzy to kolejne warunku laczace. I juz.


Wielkie dzięki, działa tak jak chciałem.. w końcu.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.