MySQL + JOIN + flera tabeller, hjälp önskas fort!

Tråden skapades och har fått 3 svar. Det senaste inlägget skrevs .
1
  • Oregistrerad
  • 2004-05-15 21:08

Hej! Jag behöver hjälp fort!

Vad jag söker är:
De senaste publiceringarna på min sida skall hämtas (det finns tre olika tabeller för detta; article, news och review) och för varje publicering så skall man räkna ut hur många kommentarer varje publicering har fått (tre st tabeller för kommentarerna också). Datan den skall hämta är:
- id
- headline
- body_text
- post_date
- post_user

Sedan skall den skriva ut allt i en lista. Det skall inte vara så att man trycker på en länk så laddar den de senaste posterna för recensioner osv.

Så om vi säger så här ett exempel:

Jag har alla tabeller tomma, inget publicerat material i dem. Jag skriver en nyhet klockan 13.00, sedan blir det en recension kl. 14.00 och en artikel kl. 15.00. På första sidan blir det listat så här:

Artikel (publicerad kl 15)
Recensionen (publicerad kl 14)
Nyheten (publicerad kl 13)

Ungefär som http://www.macfeber.se/, skall det listas på första sidan.

Snälla är det oklart vad jag menar, fråga gärna. Är beroende av denna funktion.

MVH / Patrik

OBS! De skall inte listas för sig t.ex. artiklarna först, sedan recensioner och sist nyheterna. Utan de skall sorteras efter DESC och det skall vara en limit 10.

Annars så skulle jag klara detta själv om man skulle köra varje "kategori" för sig. OBS!

#
# Table structure for table `article`
#

CREATE TABLE `article` (
  `id` int(11) NOT NULL auto_increment,
  `headline` varchar(255) NOT NULL default '',
  `body_text` text NOT NULL,
  `post_date` datetime NOT NULL default '0000-00-00 00:00:00',
  `post_user` varchar(255) NOT NULL default '',
  `changed` tinyint(4) NOT NULL default '0',
  `change_time` datetime NOT NULL default '0000-00-00 00:00:00',
  `change_user` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`)
) TYPE=MyISAM AUTO_INCREMENT=5 ;

# --------------------------------------------------------

#
# Table structure for table `article_comments`
#

CREATE TABLE `article_comments` (
  `comment_id` int(11) NOT NULL auto_increment,
  `article_id` int(11) NOT NULL default '0',
  `comment_text` text NOT NULL,
  `post_user` varchar(255) NOT NULL default '',
  `post_time` datetime NOT NULL default '0000-00-00 00:00:00',
  PRIMARY KEY  (`comment_id`)
) TYPE=MyISAM AUTO_INCREMENT=1 ;

# --------------------------------------------------------

#
# Table structure for table `news`
#

CREATE TABLE `news` (
  `id` int(11) NOT NULL auto_increment,
  `headline` varchar(255) NOT NULL default '',
  `body_text` text NOT NULL,
  `post_date` datetime NOT NULL default '0000-00-00 00:00:00',
  `post_user` varchar(255) NOT NULL default '',
  `changed` tinyint(4) NOT NULL default '0',
  `change_time` datetime NOT NULL default '0000-00-00 00:00:00',
  `change_user` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`)
) TYPE=MyISAM AUTO_INCREMENT=5 ;

# --------------------------------------------------------

#
# Table structure for table `news_comments`
#

CREATE TABLE `news_comments` (
  `comment_id` int(11) NOT NULL auto_increment,
  `news_id` int(11) NOT NULL default '0',
  `comment_text` text NOT NULL,
  `post_user` varchar(255) NOT NULL default '',
  `post_time` datetime NOT NULL default '0000-00-00 00:00:00',
  PRIMARY KEY  (`comment_id`)
) TYPE=MyISAM AUTO_INCREMENT=1 ;

# --------------------------------------------------------

#
# Table structure for table `review`
#

CREATE TABLE `review` (
  `id` int(11) NOT NULL auto_increment,
  `headline` varchar(255) NOT NULL default '',
  `artist` varchar(255) NOT NULL default '',
  `album` varchar(255) NOT NULL default '',
  `releasedate` varchar(255) NOT NULL default '',
  `genre` varchar(255) NOT NULL default '',
  `label` varchar(255) NOT NULL default '',
  `tracklist` text NOT NULL,
  `body_text` text NOT NULL,
  `post_date` datetime NOT NULL default '0000-00-00 00:00:00',
  `post_user` varchar(255) NOT NULL default '',
  `changed` tinyint(4) NOT NULL default '0',
  `change_time` datetime NOT NULL default '0000-00-00 00:00:00',
  `change_user` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`)
) TYPE=MyISAM AUTO_INCREMENT=4 ;

# --------------------------------------------------------

#
# Table structure for table `review_comments`
#

CREATE TABLE `review_comments` (
  `comment_id` int(11) NOT NULL auto_increment,
  `review_id` int(11) NOT NULL default '0',
  `comment_text` text NOT NULL,
  `post_user` varchar(255) NOT NULL default '',
  `post_time` datetime NOT NULL default '0000-00-00 00:00:00',
  PRIMARY KEY  (`comment_id`)
) TYPE=MyISAM AUTO_INCREMENT=2 ;

# --------------------------------------------------------

Följande borde fungera, observera paranteserna kring varje SELECT:
(SELECT id, headline,... FROM article)
UNION
(SELECT ...)
UNION...
ORDER BY post_date;

Däremot så har jag ingen aning om hur LIMIT fungerar med UNION.

Jag måste säga att den bästa lösningen vore att designa om databasen helt och hållet. Article, Review och News tabellerna är så lika att de borde vara en tabell med ett nytt fält som talar om vad det är för typ av information och med de extrafält som finns för Review i en separat tabell. Då skulle du dessutom bara behöva en comments tabell.

T.ex
CREATE TABLE `information` (
`id` int(11) NOT NULL auto_increment,
`type` SET( 'A', 'R', 'N' ) DEFAULT 'A' NOT NULL ,
`headline` varchar(255) NOT NULL default '',
`body_text` text NOT NULL,
`post_date` datetime NOT NULL default '0000-00-00 00:00:00',
`post_user` varchar(255) NOT NULL default '',
`changed` tinyint(4) NOT NULL default '0',
`change_time` datetime NOT NULL default '0000-00-00 00:00:00',
`change_user` varchar(255) NOT NULL default '',
PRIMARY KEY (`id`)
) TYPE=MyISAM AUTO_INCREMENT=5 ;

CREATE TABLE `comments` (
`comment_id` int(11) NOT NULL auto_increment,
`information_id` int(11) NOT NULL default '0',
`comment_text` text NOT NULL,
`post_user` varchar(255) NOT NULL default '',
`post_time` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`comment_id`)
) TYPE=MyISAM AUTO_INCREMENT=1 ;

Det blir nog lättare att underhålla samt gör dina SQL-frågor enklare.

Joakim

  • Oregistrerad
  • 2004-05-16 18:58
Ursprungligen av jocked:

Följande borde fungera, observera paranteserna kring varje SELECT:
(SELECT id, headline,... FROM article)
UNION
(SELECT ...)
UNION...
ORDER BY post_date;

Däremot så har jag ingen aning om hur LIMIT fungerar med UNION.

Jag måste säga att den bästa lösningen vore att designa om databasen helt och hållet. Article, Review och News tabellerna är så lika att de borde vara en tabell med ett nytt fält som talar om vad det är för typ av information och med de extrafält som finns för Review i en separat tabell. Då skulle du dessutom bara behöva en comments tabell.

T.ex
CREATE TABLE `information` (
`id` int(11) NOT NULL auto_increment,
`type` SET( 'A', 'R', 'N' ) DEFAULT 'A' NOT NULL ,
`headline` varchar(255) NOT NULL default '',
`body_text` text NOT NULL,
`post_date` datetime NOT NULL default '0000-00-00 00:00:00',
`post_user` varchar(255) NOT NULL default '',
`changed` tinyint(4) NOT NULL default '0',
`change_time` datetime NOT NULL default '0000-00-00 00:00:00',
`change_user` varchar(255) NOT NULL default '',
PRIMARY KEY (`id`)
) TYPE=MyISAM AUTO_INCREMENT=5 ;

CREATE TABLE `comments` (
`comment_id` int(11) NOT NULL auto_increment,
`information_id` int(11) NOT NULL default '0',
`comment_text` text NOT NULL,
`post_user` varchar(255) NOT NULL default '',
`post_time` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`comment_id`)
) TYPE=MyISAM AUTO_INCREMENT=1 ;

Det blir nog lättare att underhålla samt gör dina SQL-frågor enklare.

Joakim

Tack för ditt svar!
Dock så testade jag inte koden som du tipsade om, utan funderar starkt på att strukturera om databasen. Blir nog lite smidigare då.

Pillade ihop en lösning under dagen, med massa arrays osv funkar ju men vet ej sjutton.

Blir nog bäst och bygga nytt.

Tack. MVH / Patrik

Ursprungligen av jocked:

Däremot så har jag ingen aning om hur LIMIT fungerar med UNION.

LIMIT utförs alltid på resultatmängden av varje enskild sats. Kombinerar man ihop tre SELECT-satser med UNION och någon av satserna har ett LIMIT-direktiv kommer det alltså bara att gälla resultatet från just den satsen. För att göra en LIMIT på satsernas sammanlagda resultatmängd finns inget annat alternativ än att köra en nästlad SELECT, i stil med nedanstående:

SELECT * FROM
   (SELECT * FROM tabell1
    UNION
    SELECT * FROM tabell2
    UNION
    SELECT * FROM tabell3) AS tabeller
LIMIT 5;
1
Bevaka tråden