我最近阅读了一些关于嵌入式mysql查询的性能问题的内容,所以我想知道如何将以下内容更改为“JOIN”(假设性能更好?)。
我有两张桌子:
CREATE TABLE IF NOT EXISTS `blog_categories` (
`category_id` int(11) NOT NULL AUTO_INCREMENT,
`category_name` varchar(300) COLLATE utf8_unicode_ci NOT NULL,
`category_name_url` varchar(300) COLLATE utf8_unicode_ci NOT NULL,
`category_status` enum('online','offline') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'offline'
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=8 ;
CREATE TABLE IF NOT EXISTS `blog_articles` (
`article_id` int(11) NOT NULL AUTO_INCREMENT,
`article_title` tinytext COLLATE utf8_unicode_ci NOT NULL,
`category_name` varchar(100) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=26 ;
逻辑基本上是选择所有与其相关联的文章的类别。 blog_articles表中的每一行都包含category_name
这是我正在使用的查询(检查并正常工作):
$sql = "SELECT category_name
, category_name_url
FROM blog_categories
WHERE (
(SELECT COUNT(*)
FROM blog_articles, blog_categories
WHERE blog_articles.category_name = blog_categories.category_name
) > 0
AND blog_categories.category_status = 'online')";
我还是“JOIN”的新手,并且在混音中使用“COUNT(*)”时也不确定如何更改它。
答案 0 :(得分:5)
而不是COUNT(*) > 0
,请使用EXISTS
"SELECT category_name, category_name_url FROM blog_categories WHERE EXISTS (" .
"(SELECT 1 FROM blog_articles INNER JOIN blog_categories
ON blog_articles.category_name = blog_categories.category_name) AND " .
"blog_categories.category_status = 'online'" .
")";
这是旧式连接语法:
SELECT 1 FROM blog_articles, blog_categories
WHERE blog_articles.category_name = blog_categories.category_name
这是同样的ANSI形式:
SELECT 1
FROM blog_articles
INNER JOIN blog_categories
ON blog_articles.category_name = blog_categories.category_name
更新(响应海报评论):此查询可满足您的需求:
"SELECT category_name, category_name_url
FROM blog_categories
WHERE category_name IN (SELECT DISTINCT category_name FROM blog_articles)
AND blog_categories.category_status = 'online'"
答案 1 :(得分:1)
我使用EXISTS
:
$sql = "SELECT category_name
, category_name_url
FROM blog_categories
WHERE EXISTS
( SELECT *
FROM blog_articles
WHERE blog_articles.category_name = blog_categories.category_name
)
AND blog_categories.category_status = 'online'
";
或JOIN
:
$sql = "SELECT c.category_name
, c.category_name_url
FROM blog_categories AS c
JOIN blog_articles AS a
ON a.category_name = c.category_name
WHERE c.category_status = 'online'
GROUP BY c.category_name
";
@Jay:我怀疑你的查询是否正确,只显示有文章发布的类别。它统计所有类别的所有文章,然后显示所有类别(如果计数> 0)或根本不显示任何类别(如果计数= 0)。
原因是子查询中的blog_categories
与任何条件下的主查询中的blog_categories
无关。
答案 2 :(得分:0)
你也可以试试这个:
SELECT category_name, category_name_url
FROM blog_categories
WHERE category_id IN (
SELECT blog_categories.category_id
FROM blog_articles
INNER JOIN blog_categories
ON blog_categories.category_name = blog_articles.category_name
AND blog_categories.category_status = 'online'
)