【问题标题】:Getting mySQL stored procedure results in another stored procedure获取 mySQL 存储过程会导致另一个存储过程
【发布时间】:2011-12-29 01:00:57
【问题描述】:

我需要一个存储过程的示例,它使用另外两个存储过程(甚至只是一个)的结果,其中结果用作组合存储过程中的表。我可能会从那里拿走它。

web 上的示例(多个站点)和 php.net 上的详细信息过于简单。

基本问题可以在这里看到:

SELECT ttd.person_id, weight, min(test_date)
FROM (
  CALL get_team_member_body_stats(1) AS tbs,   
  CALL get_team_member_first_last_test_date(1) AS ttd
  WHERE tbs.person_id = ttd.person_id
  AND (tbs.test_date = ttd.first_test OR tbs.test_date = ttd.last_test)
  GROUP BY ttd.person_id;
END

感谢您的帮助。昨天和今天,我在网上搜索和实验中已经为此苦苦挣扎了几个小时。

详情:

表 1

存储过程 get_team_member_body_stats(IN team_id INT) 处理 5 个表(person、team、person_team、body_stats、person_body_stats)并生成:

person_id | body_stats_id | weight | test_date |   
  2         2               200      2011-01-01  
  4         3               250      2011-01-01  
  1         5               145      2011-03-01 
  2         6               210.4    2011-03-01 
  5         7               290      2011-03-01 
  1         8               140      2011-04-01 
  1         9               135      2011-05-01 
  4         11              245      2011-05-01 

表 2

存储过程 get_team_member_first_last_test_date(IN team_id INT) 作用于相同的表并产生:

person_id | first_test | last_test

1           2011-03-01   2011-05-01
2           2011-01-01   2011-03-01
4           2011-01-01   2011-05-01
5           2011-03-01   2011-03-01

目标是加入这些并产生:

表 3

person_id | first_weight | last_weight

1           145            135
2           200            210.4 
4           250            245
5           290            290

谢谢

【问题讨论】:

  • 我觉得这个总结很不错,+1。如果我是你,我会考虑删除其余部分(因为这不容易理解)
  • 问题:1. sp1 (IN team_id INT) 返回 person_id、weight、test_date 的“表”。 2. sp2 (IN team_id INT) 返回 person_id、start_test、last_test 的“表” 3. 尝试生成 sp3 (IN team_id INT),它将加入这些并返回 person_id、weight、start_date 的“表”。
  • 关于这个问题(我实际上不得不看原文),乍一看,在我看来,您需要的东西完全可以在没有存储过程的情况下完成。涉及多少张表?也许您可以发布 另一个问题,其中包含相关表格和您期望的结果。
  • @Lieven,坏主意。米歇尔,请对这个问题进行任何相关的编辑。
  • @MichaelPetrotta - 这将是一个完全不同的问题(这个问题无法稳健地解决)。我相信 OP 在提出这个问题时已经考虑到了一个特定的解决方案,而他/她应该不考虑这个解决方案(有一个术语,但现在我没有想到)。无论如何,这个问题已经吸引了所有的 cmets,OP 不妨删除这个并发布一个新的。

标签: mysql sql stored-procedures


【解决方案1】:

似乎(根据这个社区,并且因为我找不到任何使用来自其他存储过程的结果集作为新选择表中的表的存储过程示例)mysql 要么不支持这一点,要么很难做到做我想做的事。

所以我没有调用存储过程,而是将查询复制到这个最终过程中。

分隔符 $$ CREATE DEFINER=`root`@`localhost` PROCEDURE `get_team_stats_change`( IN team_id INT ) 开始 选择总和(开始重量)作为开始重量, SUM(start_body_fat) 作为 start_body_fat, SUM(current_weight) 作为 current_weight, SUM(current_body_fat) 作为 current_body_fat, SUM(weight_change) AS weight_change, SUM(body_fat_change) 作为 body_fat_change FROM ( 选择 ls.person_id, fs.weight AS start_weight, fs.body_fat AS start_body_fat, ls.weight AS current_weight, ls.body_fat AS current_body_fat, fs.weight - ls.weight AS weight_change, fs.body_fat - ls.body_fat AS body_fat_change 从 (选择 ttd.person_id、bs.weight、bs.body_fat、bs.test_date FROM body_stats AS bs 加入 ((SELECT pbs.person_id, min(bs.test_date) AS first_test, max(bs.test_date) AS last_test FROM body_stats AS bs, person_body_stats AS pbs, team_member AS tm, 团队 AS t WHERE t.team_id = team_id AND tm.team_id = t.team_id AND tm.person_id = pbs.person_id 和 pbs.body_stats_id = bs.body_stats_id AND tm.start_date bs.test_date AND bs.test_date >= t.starting_date GROUP BY person_id) 作为 ttd, person_body_stats AS pbs) ON bs.test_date = ttd.first_test 和 pbs.person_id = ttd.person_id AND pbs.body_stats_id = bs.body_stats_id) AS fs, (选择 ttd.person_id、bs.weight、bs.body_fat、bs.test_date FROM body_stats AS bs 加入 ((SELECT pbs.person_id, min(bs.test_date) AS first_test, max(bs.test_date) AS last_test FROM body_stats AS bs, person_body_stats AS pbs, team_member AS tm, 团队 AS t WHERE t.team_id = team_id AND tm.team_id = t.team_id AND tm.person_id = pbs.person_id 和 pbs.body_stats_id = bs.body_stats_id AND tm.start_date bs.test_date AND bs.test_date >= t.starting_date GROUP BY person_id) 作为 ttd, person_body_stats AS pbs) ON bs.test_date = ttd.last_test 和 pbs.person_id = ttd.person_id AND pbs.body_stats_id = bs.body_stats_id) AS ls WHERE ls.person_id = fs.person_id ) 作为增量; 结尾

【讨论】:

    【解决方案2】:

    我不知道您可以多么容易地从合并到临时表或视图中的 5 个表中获得这些结果,但基本上,以下应该与您当前尝试使用 3 个存储过程的结果相同。

    SELECT person_id
           , (SELECT weight 
              FROM   FiveTablesResult 
              WHERE  person_id = ftr.person_id 
                     AND test_date = (SELECT MIN(test_date) 
                                      FROM   FiveTablesResult 
                                      WHERE  person_id = ftr.person_id)
             ) AS first_weight
           , (SELECT weight 
              FROM   FiveTablesResult 
              WHERE  person_id = ftr.person_id 
                     AND test_date = (SELECT MAX(test_date) 
                                      FROM   FiveTablesResult 
                                      WHERE  person_id = ftr.person_id)
             ) AS last_weight
    FROM   FiveTablesResult ftr
    

    请注意,还有优化的空间,但让我们首先得到正确的返回结果

    【讨论】:

    • 谢谢。我有存储过程来为您称为 FiveTablesResult 的两个部分生成数据,如上面的表 1 和表 2 所示。如何将占位符“FiveTablesResult”替换为对这些存储过程的调用? ...(SELECT weight FROM (CALL get_team_member_body_stats(person_id)) WHERE ... 不起作用。
    • @Michelle - 您的方法的问题是(我知道)无法将存储过程的结果合并到普通选择中。尽管我仍然认为应该可以一起省略存储过程并使用普通的 select 语句检索您需要的数据,但要确定这一点,我们需要有一个关于您的表如何链接的架构和最好是一些测试数据和所需的结果。
    • 谢谢。我想答案是:“这做不到。”相反,我可以将 Select 语句放在 php.ini 中。我不想这样做,因为它会吓到网站所有者/开发人员。我要做的是在单独的文件中创建一个 php 函数库,并向他展示如何为他需要调用的函数进行包含。不理想但可行。或者我应该将视图视为创建前端开发人员可以使用的“函数”库的一种方法?再次感谢您考虑我的问题。
    • @Michelle - 据我所知无法做到这一点,这是一个重要的区别。那么如何在 PHP 中最好地解决这个问题也超出了我的范围。 PHP 真的不是我的强项。
    • 只是为了总结一下。我创建了一个不从其他存储过程构建的存储过程。这是我所做的:
    猜你喜欢
    • 2011-05-05
    • 2018-03-04
    • 2017-06-19
    • 2011-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多