MySql结果集为n * n

时间:2017-04-29 13:32:36

标签: mysql sql

我有以下表格:

  1. 标签
  2. tag_names
  3. workout_names
  4. workout_tags
  5. 锻炼
  6. 我的目标是在结果集中检索锻炼和标签,就像这样。

    workout
    workout_tags
    
    workout
    workout_tags
    

    我可以检索一个不是问题的那个:

    DELIMITER $$
    
    CREATE PROCEDURE get_workouts_menu(IN _language SMALLINT(255))
    BEGIN
    
    DECLARE workout_id INTEGER;
    
    SELECT w.workout_id,ROUND((w.duration / 1000) / 60) AS duration,w.isCustom,w.purchased,wn.name FROM workouts AS w INNER JOIN workout_names AS wn ON w.workout_id=wn.workout_id WHERE wn.language=_language ORDER BY  w.isCustom DESC,wn.name ;
    
    #workout_id = QUERY ABOVE... you get the point
    
    #SELECT tag_id FROM workout_tags WHERE workout_id = workout_id;
    
    #SELECT * FROM tag_names WHERE tag_id = nn;
    
    END$$
    

    你明白了,我的问题是如何能够检索多个锻炼表和多个标签表。如果有更多的话,我还有保存id的问题。正如你在上面的代码中看到的那样,我可以得到,但我怎么能一个接一个,或者如果有人有更好的方法。谢谢......

1 个答案:

答案 0 :(得分:-1)

您无法在单个SQL结果集中获得两种不同类型的结果 - 您不能将锻炼信息行与标记信息混合在一起。

有两种方法可以做到这一点。您可以加入表格,每个标签都有单独的行 - 它们将具有重复的锻炼信息。调用应用程序可以显示序列中第一行的锻炼信息,并跳过后续行。有关如何在PHP中执行此操作,请参阅How can i list has same id data with while loop in PHP?

或者您可以使用GROUP_CONCAT将逗号分隔列表中的所有标记名称与锻炼信息放在同一行中。然后,调用应用程序可以拆分此列表,以在嵌套循环中的不同行上显示它们。

SELECT w.workout_id,ROUND((w.duration / 1000) / 60) AS duration,w.isCustom,w.purchased,wn.name, 
        GROUP_CONCAT(tn.name) AS tags
FROM workouts AS w 
INNER JOIN workout_names AS wn ON w.workout_id=wn.workout_id
LEFT JOIN workout_tags AS wt ON wt.workout_id = w.workout_id
LEFT JOIN tag_names AS tn ON tn.nn = wt.tag_id
WHERE wn.language=_language 
GROUP BY w.workout_id
ORDER BY  w.isCustom DESC, wn.name ;