如何使用mysql中的存储过程获取问题及其相关标签?

How to get the questions and its related tags using store procedure in mysql?

我有一个 questions table 和

  1. id
  2. 标题
  3. body


tags table 和

  1. id
  2. 名字
  3. 描述

最后 question_tags 关系 table 与

  1. id
  2. tag_id
  3. question_id


我有以下代码可以使用 mysql 存储过程获取所有问题。

I need to get the question details and its related tag details using a store procedures (like this <question details,tag1 details,tag2 details... tag5 details>).
I thought about storing the tag's id along with the question table ,but for retrieving the tag details I had to write another query which store procedure doesn't allow me to do.Same issue when trying to get tag details after getting the question id.
I tried my level best ,but yet don't know how to solve it.
any ideas or suggestions? thanks
I tried my best to explain the situation .

这是找出输出结构的基本查询,如下所示:

 question_id    title   FirstTagName    FirstTag    SecondTagName   SecondTag   ThirdTagName    ThirdTag    FourthTagName   FourthTag   FifthTagName    FifthTag

查询:

SELECT 
t.question_id,
t.title,
MAX(CASE WHEN t.constantTagNumber = 1 THEN t.name END) AS FirstTagName,
MAX(CASE WHEN t.constantTagNumber = 1 THEN t.description END) AS FirstTag,
MAX(CASE WHEN t.constantTagNumber = 2 THEN t.name END) AS SecondTagName,
MAX(CASE WHEN t.constantTagNumber = 2 THEN t.description END) AS SecondTag,
MAX(CASE WHEN t.constantTagNumber = 3 THEN t.name END) AS ThirdTagName,
MAX(CASE WHEN t.constantTagNumber = 3 THEN t.description END) AS ThirdTag,
MAX(CASE WHEN t.constantTagNumber = 4 THEN t.name END) AS FourthTagName,
MAX(CASE WHEN t.constantTagNumber = 4 THEN t.description END) AS FourthTag,
MAX(CASE WHEN t.constantTagNumber = 5 THEN t.name END) AS FifthTagName,
MAX(CASE WHEN t.constantTagNumber = 5 THEN t.description END) AS FifthTag
FROM
(
    SELECT
        question_id,
        questions.title,
        tag_id,
        tags. NAME,
        tags.description,
        IF (@prev = question_id ,@c := @c + 1,@c := 1) constantTagNumber,
        @prev := question_id
    FROM    (   SELECT @prev := 0 ,@c := 1) var,    questions_tags
    INNER JOIN tags ON tags.id = questions_tags.tag_id
    INNER JOIN questions ON questions_tags.question_id = questions.ID
    ORDER BY    question_id,    tag_id
) t
GROUP BY t.question_id;

======>DEMO HERE<======

解释:

先看内查询:

SELECT
            question_id,
            questions.title,
            tag_id,
            tags. NAME,
            tags.description,
            IF (@prev = question_id ,@c := @c + 1,@c := 1) constantTagNumber,
            @prev := question_id
        FROM    (   SELECT @prev := 0 ,@c := 1) var,    questions_tags
        INNER JOIN tags ON tags.id = questions_tags.tag_id
        INNER JOIN questions ON questions_tags.question_id = questions.ID
        ORDER BY    question_id,    tag_id;

DEMO OF IT

看,此查询中没有 group by 子句。我试图通过此查询实现的是:

  • 获取所有问题和标签,以便选择所有记录 来自 questions_tags table 粘在一起越来越多 tag ids(由 ORDER BY question_id,tag_id 子句完成)
  • 我用了两个mysql user variables (e.g. @prev and @c)。问题 ID 存储在 @prev 变量中。在遍历 questions_tags table 中的行时,如果我看到一个新的 question_id,那么我将变量 @c 重置为 1
  • @c 变量为 tags.id 字段分配一个标记号,与原始 tag_number 无关。既然你告诉 tags 可以有无限多个,但是每个问题最多可以有五个标签,所以变量 @c 的范围将是 1 to 5 i.e. [1,5].
  • 内部查询生成此 result set
  • 现在外部查询开始发挥作用了。最外面的查询中有一个 group by 子句。所以每个问题你都会得到一行。
  • MAX(CASE WHEN t.constantTagNumber = 1 THEN t.name END)这一行的作用是保证第一个标签描述会放到最终结果集中对应的列中。它叫做 pivoting.

请花点时间查看内部查询。然后想想你自己"How can I generate the final result set from this table?"。

如果您需要任何帮助,请随时提出。