SQL。循环遍历不同表中的列以计算值

时间:2016-12-29 19:12:03

标签: sql for-loop while-loop case

我想计算有多少司机开得太快了。我有一张桌子 交通。 在每一行的这张表中,我可以看到有多少车在不同的速度类别中驾驶。对于这个问题,我只需要amount_drivers1列,直到amount_drivers10。

我在表speedcategories中有十种不同的速度类别(例如speed_categorie第1-10列的值为:20,30,40,50,60,70,80,90,100,110) 这些是不同的方式。对于每一行,我必须找到单程的速度类别。 Speed_categorie1与amount_drivers1有关,speed_categorie2与amount_drivers2有关...

然后我必须使用表MAX_SPEED中的max_speed列。我必须遍历每个speed_categorie列以查看speed_categorie是否高于max_speed列。如果不做什么,如果是,则来自流量表的汽车数量(列amount_drivers的值)必须进入“to_hard”列。

max_speed,speed_categories和流量表之间的关系是id号。这些是外键。这是图表:

LRS of database

例如max_speed = 60(来自max_speed_table)。然后只有速度类别70,80,90,100和110(来自speed_categorie表)才有资格。然后来自amount_drivers6,amount_drivers7,amount_drivers8,amount_drivers9和amount_drivers10(来自流量表)的驱动量必须进入“to_hard”列。因此,在这种情况下,这是列amount_drivers6,amount_drivers7,amount_drivers8,amount_drivers9和amount_drivers10的总和。此总和必须在“to_hard”列中。

2 个答案:

答案 0 :(得分:0)

首先尝试使用此SP,EXEC CheckOverSpeed 1获取way1的总数,其余部分相同,如果您需要自动获取所有方式的列表,请告诉我,但我能做的第一件事想到正在使用cursor,如果你熟悉这个,你可以对我的SP进行更改

CREATE PROCEDURE CheckOverSpeed

(@ID_input INT)

AS
BEGIN

DECLARE @amount_drivers1 INT
DECLARE @amount_drivers2 INT
DECLARE @amount_drivers3 INT
DECLARE @amount_drivers4 INT
DECLARE @amount_drivers5 INT
DECLARE @amount_drivers6 INT
DECLARE @amount_drivers7 INT
DECLARE @amount_drivers8 INT
DECLARE @amount_drivers9 INT
DECLARE @amount_drivers10 INT


DECLARE @SPEED_CAT1 INT
DECLARE @SPEED_CAT2 INT
DECLARE @SPEED_CAT3 INT
DECLARE @SPEED_CAT4 INT
DECLARE @SPEED_CAT5 INT
DECLARE @SPEED_CAT6 INT
DECLARE @SPEED_CAT7 INT
DECLARE @SPEED_CAT8 INT
DECLARE @SPEED_CAT9 INT
DECLARE @SPEED_CAT10 INT


DECLARE @MAX_SPEED_ID INT
DECLARE @ID INT
DECLARE @SUM INT = 0

SELECT @ID = @ID_input, 
       @amount_drivers1 = T.amount_drivers1,
       @amount_drivers2 = T.amount_drivers2,
       @amount_drivers3 = T.amount_drivers3,
       @amount_drivers4 = T.amount_drivers4,
       @amount_drivers5 = T.amount_drivers5,
       @amount_drivers6 = T.amount_drivers6,
       @amount_drivers7 = T.amount_drivers7,
       @amount_drivers8 = T.amount_drivers8,
       @amount_drivers9 = T.amount_drivers9,
       @amount_drivers10 = T.amount_drivers10,

       @SPEED_CAT1 = S.SPEED_CAT1,
       @SPEED_CAT2 = S.SPEED_CAT2,
       @SPEED_CAT3 = S.SPEED_CAT3,
       @SPEED_CAT4 = S.SPEED_CAT4,
       @SPEED_CAT5 = S.SPEED_CAT5,
       @SPEED_CAT6 = S.SPEED_CAT6,
       @SPEED_CAT7 = S.SPEED_CAT7,
       @SPEED_CAT8 = S.SPEED_CAT8,
       @SPEED_CAT9 = S.SPEED_CAT9,
       @SPEED_CAT10 = S.SPEED_CAT10,

       @MAX_SPEED_ID = M.MAX_SPEED_ID

FROM
TRAFFIC as T 
INNER JOIN MAX_SPEED as M
ON M.MAX_SPEED_ID = T.ID
INNER JOIN SPPED_CATEGORIES as S
ON S.ID = T.ID
WHERE T.ID = @ID

SET @SUM = CASE WHEN  @SPEED_CAT1<@MAX_SPEED_ID THEN 0 ELSE @amount_drivers1 END +
           CASE WHEN  @SPEED_CAT2<@MAX_SPEED_ID THEN 0 ELSE @amount_drivers2 END +
           CASE WHEN  @SPEED_CAT3<@MAX_SPEED_ID THEN 0 ELSE @amount_drivers3 END +
           CASE WHEN  @SPEED_CAT4<@MAX_SPEED_ID THEN 0 ELSE @amount_drivers4 END +
           CASE WHEN  @SPEED_CAT5<@MAX_SPEED_ID THEN 0 ELSE @amount_drivers5 END +
           CASE WHEN  @SPEED_CAT6<@MAX_SPEED_ID THEN 0 ELSE @amount_drivers6 END +
           CASE WHEN  @SPEED_CAT7<@MAX_SPEED_ID THEN 0 ELSE @amount_drivers7 END +
           CASE WHEN  @SPEED_CAT8<@MAX_SPEED_ID THEN 0 ELSE @amount_drivers8 END +
           CASE WHEN  @SPEED_CAT9<@MAX_SPEED_ID THEN 0 ELSE @amount_drivers9 END +
           CASE WHEN  @SPEED_CAT10<@MAX_SPEED_ID THEN 0 ELSE @amount_drivers10 END

PRINT 'The total number of over speed drivers for way '+CAST(@ID as varchar(50)) + ' is '+ CAST(@SUM as varchar(100)) 

END

答案 1 :(得分:0)

首先,这不是一个好的表结构。如果要存储此类数据,最好创建另一个密钥,并将 Model.update_all(created_at: Time.now, updated_at: Time.now) 列作为单个列存储在多行中。 amount_drivers也是如此。事实上,没有太多理由使用SPEED_CAT表,因为您有固定数量的列。但是,如果这些值发生变化,我会在下面使用它们。

其次,这是我可以从你的结构和所需的输出中收集到的最好的,没有数据来支持它。查看有关您问题的评论。

SPEED_CATEGORIES