如何在select或table的每一行中执行过程

时间:2015-11-05 23:18:26

标签: mysql sql

我试图分析NBA的球队时间表,我需要在这个查询中的每一行都运行一个程序......

SELECT
    t.teamname AS team,
    opp.teamname AS opponent, 
    cat.cityname AS at,
    COUNT( * ) AS GamesInCity,
    ( COUNT( * )/ @daysinseason ) AS Pct
FROM schedules s
    INNER JOIN teams t   ON s.teamid     = t.teamid
    INNER JOIN teams opp ON s.oppteamid  = opp.teamid
    INNER JOIN teams at  ON s.hometeamid = at.teamid
    INNER JOIN city c    ON t.cityid     = c.cityid
    INNER JOIN city copp ON opp.cityid   = copp.cityid
    INNER JOIN city cat  ON at.cityid    = cat.cityid
WHERE
    t.teamname = @team
GROUP BY
    cat.cityname

或将查询输出为最终看起来像这样的tmp表:

enter image description here

我理解游标并不理想,所以最好的方法是什么,或者我怎么能这样做?像这样的东西?

SELECT
    t.teamname AS team,
    opp.teamname AS opponent, 
    cat.cityname AS at,
    COUNT( * ) AS GamesInCity,
    ( COUNT( * )/ @daysinseason ) AS Pct, 
    --
    CALL name_of_proc(IN @var, IN (COUNT( * )/ @daysinseason), OUT @out)
    --
FROM
    schedules s
    INNER JOIN teams t   ON s.teamid     = t.teamid
    INNER JOIN teams opp ON s.oppteamid  = opp.teamid
    INNER JOIN teams at  ON s.hometeamid = at.teamid
    INNER JOIN city c    ON t.cityid     = c.cityid
    INNER JOIN city copp ON opp.cityid   = copp.cityid
    INNER JOIN city cat  ON at.cityid    = cat.cityid
WHERE
    t.teamname = @team
GROUP BY
    cat.cityname

注意:我必须在我的被调用过程中使用列pct。

感谢。

更新:程序是:

SET @team = 'Atlanta Hawks';
SET @daysinseason = 199;
SET @salary = 10000000;
SET @country = 'US';
SET @state = 'NY';
SET @filer= 'SINGLE';

CALL calc_state_tax(@salary, @state, @filer, @staxesDue);

CREATE PROCEDURE `calc_state_tax`(IN `pSalary` DECIMAL(12,2), IN `pStateCode` VARCHAR(2), IN `pFiler` VARCHAR(6), OUT `taxesDue` DECIMAL(9,2)
    )
        LANGUAGE SQL
        NOT DETERMINISTIC
        CONTAINS SQL
        SQL SECURITY DEFINER
        COMMENT ''
    BEGIN
    DECLARE taxRate DECIMAL(9,4);
    DECLARE taxExempt DECIMAL(7,2);
    DECLARE deduction DECIMAL(7,2);

    SELECT
        s1.taxrate,
        s1.exemption,
        s1.stddeduction
        INTO taxRate, taxExempt, deduction
    FROM statetax s1
    WHERE s1.statecode = pStateCode  
        AND s1.filer = pFiler 
        AND s1.bracket = (
        SELECT MAX( s2.bracket) 
        FROM statetax s2
        WHERE s1.statecode = s2.statecode
        AND s1.filer = s2.filer
        AND s2.bracket < pSalary);

    SET taxesDue = (((pSalary - deduction) * taxRate));

    END

2 个答案:

答案 0 :(得分:0)

您必须使用光标。您不能在select语句中为每行结果执行过程。

Select语句全部或全无,因此您必须首先使用结果集填充游标或临时表,然后单独循环每一行。没有办法,它是为游标制作的。他们没有错。

答案 1 :(得分:0)

你无法在一个选择中执行一个程序,没有办法。

解决方法是将结果转换为临时表或表变量,使用游标循环并执行每行的过程并使用更新将结果附加到表中,我认为这是不必要的

如果您将过程更改为UDF,则可以完成所需的操作,可以在查询中内联函数,因为您希望该过程为

SELECT
    t.teamname AS team,
    opp.teamname AS opponent, 
    cat.cityname AS at,
    COUNT( * ) AS GamesInCity,
    ( COUNT( * )/ @daysinseason ) AS Pct, 
    dbo.MyUDF(@var,(COUNT( * )/ @daysinseason)) -- the udf should return what you have as output parameter in your procedure
FROM ...