MySQL - polecenie wyświetlające dane z dwóch tabel

0

Witam serdecznie,
Mam 2 tabele MySQL:

CREATE TABLE IF NOT EXISTS `cms_newsy` (
  `bf_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `tytul` varchar(85) COLLATE utf8_unicode_ci DEFAULT NULL,
  `idserialu` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `datadodania` datetime NOT NULL,
  UNIQUE KEY `id` (`bf_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;


CREATE TABLE IF NOT EXISTS `cms_filmy` (
  `bf_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `tytul` varchar(250) COLLATE utf8_unicode_ci DEFAULT NULL,
  UNIQUE KEY `id` (`bf_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;


Chciałbym wyświetlić wszystkie rekordy z bazy cms_filmy które dotyczą filmów spełniających następujące warunki:
a) sortowanie filmów od tych które mają najwięcej newsów - do tych które mają najmniej
b) newsy które bierzemy pod uwagę muszą mieścić się w obszarze max 3 miesięcy - licząc od "dzisiaj"
c) jeden news może dotyczyć paru filmów

cms_newsy.idserialu = cms_filmy.bf_id
cms_newsy.idserialu = |nr_id_filmu1|nr_id_filmu2|nr_id_filmu3|nr_id_filmu4|

Próbowałem już różnych sposobów, ale nie mam pojęcia jak mogę to połączyć...

Czy mógłbym prosić o pomoc z tym zapytaniem?

Z góry dziękuję za pomoc,
NOrthwest

1

Ogólnie struktura Twojej bazy nie sprzyja takim zapytaniom...

Powinno zadziałać coś takiego:

SELECT f.*,COUNT(n.bf_id) ilosc_newsow FROM cms_filmy f
JOIN cms_newsy n ON (f.bf_id=n.idserialu OR n.idserialu LIKE CONCAT('%|',f.bf_id,'|%')) AND UNIX_TIMESTAMP(datadodania)>UNIX_TIMESTAMP(NOW())-7776000
GROUP BY f.bf_id
ORDER BY ilosc_newsow DESC

jednak z wydajnością to za wiele wspólnego nie będzie miało. Join na różnych typach pól, dodatkowo z użyciem like to delikatna kicha.

Zdecydowanie lepiej byłoby wprowadzić trzecią tabelę, łączącą id_filmu z id_newsa. Można będzie dzięki temu przypisać newsa do kilku filmów (zatem Twoje wymagania będą spełnione), a i łatwiej będzie wyszukiwać czegoś w bazie korzystając z indeksów.

0

dziękuję - zadziałało :)

0

Witam :)
Dodałem tą dodatkową tabelkę:

 
CREATE TABLE IF NOT EXISTS `cms_newsy_polaczenia` (
  `bf_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `idnewsa` int(11) DEFAULT NULL,
  `idserialu` int(11) DEFAULT NULL,
  UNIQUE KEY `id` (`bf_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1;

Mógłbym prosić o pomoc z tą dodatkową tabelką??? :)

1

W takim przypadku trzeba zrobić złączenie po dwóch tabelach:

SELECT f.*,COUNT(n.bf_id) ilosc_newsow FROM cms_filmy f
INNER JOIN cms_newsy_polaczenia np ON f.bf_id=np.idserialu
INNER JOIN cms_newsy n ON np.idnewsa=n.bf_id AND UNIX_TIMESTAMP(datadodania)>UNIX_TIMESTAMP(NOW())-7776000
GROUP BY f.bf_id
ORDER BY ilosc_newsow DESC
0

Działa. Dziękuję bardzo :)

0

Mam jeszcze jedno pytanie :)

 CREATE TABLE IF NOT EXISTS `ulubione` (
  `bf_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `idusera` int(11) DEFAULT NULL,
  `idrekordu` int(11) DEFAULT NULL,
  UNIQUE KEY `id` (`bf_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;

ulubione.idrekordu = filmy.id

chciałbym ułożyć filmy według tego, ile razy powtarzają się w "ulubione" :)
(czyli sortowanie po tym, ile razy film występuje w ulubionych).

Przepraszam że tam męcze - ale to już chyba ostatnie pytanie

Jeszcze raz dziękuję za pomoc.

0

Trzeba to napisać analogicznie do jednego z powyższych zapytań.

SELECT f.*,COUNT(u.bf_id) ilosc_ulubionych FROM cms_filmy f
INNER JOIN ulubione u ON f.bf_id=u.idrekordu
GROUP BY f.bf_id
ORDER BY ilosc_ulubionych DESC
0

dzięki :)
to zapytanie ma jeden problem - nie wyświetla filmów których nikt nie ma w ulubionych - a powinien... da się to jakoś obejść??:)

1
SELECT f.*,IFNULL(COUNT(u.bf_id),0) ilosc_ulubionych FROM cms_filmy f
LEFT JOIN ulubione u ON f.bf_id=u.idrekordu
GROUP BY f.bf_id
ORDER BY ilosc_ulubionych DESC

1 użytkowników online, w tym zalogowanych: 0, gości: 1