简体   繁体   English

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

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

I have a questions table with我有一个questions

  1. id ID
  2. title标题
  3. body身体

And


A tags table with一个tags

  1. id ID
  2. name姓名
  3. description描述

And finally a question_tags relation table with最后是一个question_tags关系表

  1. id ID
  2. tag_id tag_id
  3. question_id问题编号


I have the below code to get all the questions using mysql store procedures .我有以下代码可以使用 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> ).我需要使用存储过程获取问题详细信息及其相关标签详细信息(例如<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.我想过将标签的 id 与问题表一起存储,但是为了检索标签详细信息,我必须编写另一个查询,哪个存储过程不允许我这样做。在获取问题 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 .我尽力解释情况。

Here's the basic query for finding out the output structure like below:这是找出输出结构的基本查询,如下所示:

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

Query:询问:

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<====== ======>演示在这里<======

Explanation:解释:

First look at the inner query:先看内部查询:

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它的演示

Look there's no group by clause in this query.看看这个查询中没有group by子句。 What I tried to achieve through this query is :我试图通过这个查询实现的是:

  • To get all the questions and tags so that all the records selected from questions_tags table stick together having increasing number of tag ids (done by ORDER BY question_id,tag_id clause)获取所有问题和标签,以便从questions_tags表中选择的所有记录粘在一起,并具有越来越多的tag ids (由ORDER BY question_id,tag_id子句完成)
  • I used two mysql user variables ( eg @prev and @c ).我使用了两个mysql user variableseg @prev and @c )。 The question ID is stored in @prev variable.问题 ID 存储在 @prev 变量中。 While traversing the rows in questions_tags table if I see a new question_id then I reset the variable @c to 1 .在遍历questions_tags表中的行时,如果我看到一个新的question_id然后我将变量@c重置为1
  • The @c variable assigns a tag number for the tags.id field which is irrespective of the original tag_number . @c变量为 tags.id 字段分配一个标签编号,该编号与原始tag_number Since you told that there can be infinite number of tags but each question can have at most five tags so the range of variable @c will be 1 to 5 ie [1,5] .由于您告诉过可以有无限多个tags但每个问题最多可以有五个标签,因此变量@c的范围将是1 to 5 ie [1,5]
  • The inner query generates this result set内部查询生成这个结果集
  • Now the outer query comes into play.现在外部查询开始发挥作用。 There's a group by clause in the outer most query.在最外面的查询中有一个group by子句。 So you will get a single row for each question.因此,您将获得每个问题的一行。
  • MAX(CASE WHEN t.constantTagNumber = 1 THEN t.name END) the role of this line is to ensure that the first tag description will be put in the corresponding column in the final result set. MAX(CASE WHEN t.constantTagNumber = 1 THEN t.name END)这一行的作用是保证第一个标签描述会放在最终结果集中对应的列中。 It's called pivoting .这叫做pivoting

Please spend some time looking on the inner query.请花一些时间查看内部查询。 Then think yourself "How can I generate the final result set from this table?".然后想想自己“我怎样才能从这个表中生成最终结果集?”。

If you need any help then feel free to ask.如果您需要任何帮助,请随时询问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM