【发布时间】:2009-12-23 01:38:36
【问题描述】:
我有 2 张桌子。表 1 是“文章”,表 2 是“article_categories”。当用户创建一篇文章时,它被存储到“文章”中。用户在创建文章时可以选择该文章可以出现在其下的各种类别。目前,一篇文章可以选择属于10-25个类别中的任何一个(将来可能会增加)。归档文章的这些类别存储在“article_categories”中。因此,这意味着单个文章 ID 可以在表“article_categories”中具有多个相关值。从两个表中检索所有值时,我需要提取“article_categories”中的所有值并将这些值存储在一个数组中。
我的问题是要使用什么 SQL 查询来做到这一点?我应该使用内连接、左连接、外连接...吗?最好的方法是什么?我确实在 phpmyadmin 中尝试了其中的一些连接,它们给了我同一篇文章的重复值,而事实上,该文章应该只获取一次,并且所有相关类别都可以获取。我想在同一个查询中完成所有这些操作,而不必将查询拆分为 2 个不同的查询来完成此操作。我附上了我的表格结构,这样对你来说很容易:
CREATE TABLE IF NOT EXISTS `articles` (
`article_id` int(11) unsigned NOT NULL auto_increment,
`creator_id` int(11) unsigned NOT NULL,
`article_title` varchar(150) NOT NULL,
`article_status` varchar(10) NOT NULL,
PRIMARY KEY (`article_id`),
KEY `buyer_id` (`creator_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
--
-- Dumping data for table `articles`
--
INSERT INTO `articles` (`article_id`, `creator_id`, `article_title`, `article_status`) VALUES
(1, 1, 'My article 1', 'Pending');
CREATE TABLE IF NOT EXISTS `article_categories` (
`article_id` int(11) unsigned NOT NULL,
`category_id` smallint(3) unsigned NOT NULL,
PRIMARY KEY (`article_id`,`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `article_categories`
--
INSERT INTO `article_categories` (`article_id`, `category_id`) VALUES
(1, 1),
(1, 2),
(1, 3),
(1, 4),
(1, 5),
(1, 36),
(1, 71);
另外请注意,我在 article_categories 表中的 article_id 和 category_id 键上有一个复合键。我使用的示例查询如下:
SELECT *
FROM articles, article_categories
WHERE articles.article_id = article_categories.article_id
AND articles.article_id = 1;
这会导致:
article_id creator_id article_title article_status article_id category_id
1 1 My article 1 Pending 1 1
1 1 My article 1 Pending 1 2
1 1 My article 1 Pending 1 3
1 1 My article 1 Pending 1 4
1 1 My article 1 Pending 1 5
1 1 My article 1 Pending 1 36
1 1 My article 1 Pending 1 71
可以看出,articles 表中的值是重复的,并且它还能够获取所有类别(它是最后一列,以防格式混乱)。我只想从文章表中获取一次值并在循环中获取 category_id,以便我可以将这些循环值添加到数组中并继续我的处理。这是我从上面获取值后打算做的事情:
<?php
//i wanted to check if the article_id exists before i pull the related categories.
//If I do it this way and output using mysql_num_rows, it gives me value 7,
//when in fact, the there's only 1 article with such Id. This means it also counts
// the number of categories. Is there a way to uniquely identify only the number of
// articles (just to see if it exists or not, in the place)
$result = mysql_query("SELECT *
FROM articles, article_categories
WHERE articles.article_id = article_categories.article_id
AND articles.article_id = 1");
while ( $rows = mysql_fetch_array($result) )
{ //i don't think this the following 2 assignments should be done in the loop
$article_id = $rows['article_id'];
$article_title = $rows['article_title'];
//(loop all the category_id from the 2nd table and add to the array below)
$categories_id[] .= ??????? --> How do i do this?
}
?>
显然,我不能在上面执行 LIMIT 1,因为这会限制我检索所有类别 ID 的能力。
所以我的问题是如何从第二个表中获取所有 category_id(在一个循环中)并将它们添加到数组中,同时确保表 1 中的值只获取一次(我确实意识到从表 1 中获取的值是相同的,但循环它们没有意义)。为了实现这一点,我想获得您关于我应该使用哪种 Join 来以最高效率执行查询并使用最少资源的输入,所有这些都在一个查询中以最大限度地减少对数据库的命中。我希望这是有道理的。
提前致谢。
【问题讨论】: