【问题标题】:Write one SQL query for multiple values为多个值编写一个 SQL 查询
【发布时间】:2014-10-27 02:35:37
【问题描述】:

我正在为一个论坛创建一个简单的数据库。我有一个类别表forum_categories,如下所示:

`cat_id` INT(8) NOT NULL AUTO_INCREMENT,
`cat_title` VARCHAR(255) NOT NULL,
`cat_desc` TEXT NOT NULL,
PRIMARY KEY (`cat_id`),
UNIQUE KEY (`cat_title`)

还有一个主题表forum_topics,如下所示:

`topic_id` INT(8) NOT NULL AUTO_INCREMENT,
`cat_id` INT(8) NOT NULL COMMENT 'foreign key with forum_categories table',
`user_id` INT(11) NOT NULL COMMENT 'foreign key with users table',
`topic_title` VARCHAR(255) NOT NULL,
`topic_desc` TEXT NOT NULL, 
`topic_date` DATETIME DEFAULT NULL,
PRIMARY KEY (`topic_id`),
FOREIGN KEY (`cat_id`) REFERENCES forum_categories (`cat_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='forum topics';

现在,当我选择一个类别时,我只想显示主题,其中 cat_id 字段彼此相等。

示例:
类别 1 的 cat_id = 1
类别 2 的 cat_id = 2

主题 1 的 cat_id = 1
主题 2 的 cat_id = 2

现在选择类别1时,我只想显示主题1。如果选择 category2,我只想显示主题 2。
这个查询实现了:

SELECT * 
FROM forum_categories fc 
JOIN forum_topics ft ON fc.cat_id = ft.cat_id 
WHERE fc.cat_id = 1 
ORDER BY ft.topic_date DESC

现在,如果可能的话,我不希望每个类别都有一个查询。尝试这样做:

SELECT * 
FROM forum_categories fc 
JOIN forum_topics ft ON fc.cat_id = ft.cat_id 
WHERE fc.cat_id = ft.cat_id 
ORDER BY ft.topic_date DESC

或者这个:

SELECT * 
FROM forum_categories fc 
JOIN forum_topics ft ON fc.cat_id = ft.cat_id 
ORDER BY ft.topic_date DESC

在两个类别中显示主题 1 和 2。有没有办法对所有类别进行一次查询?

【问题讨论】:

  • 而不是在 fc.cat_id = ft.cat_id 等正确别名上使用“使用”
  • 类似 SELECT * FROM forum_categories fc JOIN forum_topics ft on fc.cat_id = ft.cat_id ORDER BY ft.topic_date DESC
  • 谢谢!它不起作用,但我想我在其他地方犯了一个错误!感谢您的帮助!
  • 有没有办法对所有类别进行一次查询?尝试接受类别 ID 作为输入的存储过程或参数化查询
  • 我认为参数化查询是您正在寻找的 OP。如果您想要更改的只是输入值,这是编写可重用查询的好方法。我的回答涵盖了这一点以及对准备好的语句的 MySQL 参考。如果您有任何问题,请告诉我。

标签: mysql sql select prepared-statement


【解决方案1】:

如果您想创建一个查询来提取所有类别的数据,您可以将两个表连接在一起,条件是 cat_id 相等。这看起来像这样:

SELECT * 
FROM forum_categories fc
JOIN forum_topics ft ON fc.cat_id = ft.cat_id
ORDER BY ft.topic_date DESC;

如果要查询特定类别,可以将其放在 WHERE 语句中,如下所示:

SELECT * 
FROM forum_categories fc
JOIN forum_topics ft ON fc.cat_id = ft.cat_id
WHERE fc.cat_id = 1 // Or whatever you want.
ORDER BY ft.topic_date DESC;

我认为您可能遇到的一个问题是您希望它可重用,您可以在其中编写一个查询并根据需要更改 cat_id。如果是这种情况,我建议您查看准备好的语句。

预准备语句的作用是使用您根据需要插入的参数值创建查询。这是一个例子:

PREPARE stmnt FROM 
    'SELECT * 
    FROM forum_categories fc
    JOIN forum_topics ft ON fc.cat_id = ft.cat_id
    WHERE fc.cat_id = ?
    ORDER BY ft.topic_date DESC';

SET @a = 1;

EXECUTE stmnt USING @a;

当你这样做时,你可以用你想要的任何东西分配一个新的变量(@b,@c)。您所要做的就是每次调用EXECUTE stmnt,而不必总是重写该查询。

这是一个SQL Fiddle,涵盖了我为您提供的所有三个示例。

这里是对 MySQL prepared statements 的引用。

【讨论】:

  • 哇!多么惊人的答案!太感谢了!!!我不能升级这个,但只要我有足够的声誉,我就会升级。
  • 没有必要为此感到压力——我是来帮忙的,这就是我所做的。这是一个很好的问题,我给了它+1。不断提出这些发人深省的棘手问题,您很快就会建立自己的声誉。
【解决方案2】:

请尝试以下方法:

SELECT *
  FROM forum_categories fc
  JOIN forum_topics ft
    ON fc.cat_id = ft.cat_id
 WHERE fc.cat_id = 1 -- or whatever category you want
 ORDER
    BY ft.topic_date DESC

【讨论】:

  • 没有错误消息,它只显示所有主题,无论我选择哪个类别。我想我在其他地方犯了一个错误。感谢您的帮助!
  • 好吧,如果你只想要一个特殊的类别,你需要一个额外的 WHERE 子句(见我更新的答案)
  • 哇!!这样可行!我有可能做类似 WHERE fc.cat_id = ft.cat_id 的事情吗?因为我想对所有类别进行一次查询。不是每个类别的单独查询,如果可能的话?
  • 你已经做到了。 WHERE fc.cat_id = ft.cat_id 只是连接两个表的另一种方式。
  • 嗯...这是没有 WHERE 子句的查询。它返回具有相应类别的所有主题。
【解决方案3】:
SELECT
   cat_title,
   cat_desc,
   topic_title,
   topic_desc
FROM forum_categories
INNER JOIN forum_topics
   USING(cat_id)
WHERE cat_id = x;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-27
    • 2019-07-25
    • 2022-06-14
    • 2018-07-03
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多