【问题标题】:SQL. Looping through columns from different tables to calculate valueSQL。循环遍历来自不同表的列以计算值
【发布时间】:2017-05-14 03:24:13
【问题描述】:

我想计算有多少司机开得太快了。我有一张桌子 交通。 在每一行的这张表中,我可以看到有多少汽车以不同的速度类别行驶。对于这个问题,我只需要从 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 编号。这些是外键。这是图表:

例如 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”列中。

【问题讨论】:

  • 虽然是编程的标准方法,但循环不是 SQL 的方法。您需要编写一个同时检查所有行的查询,并使用Count () 提供摘要。使用示例数据集创建一个 SQL fiddle,我们可以为您提供更多建议。
  • 您需要向我们提供 3 个表中的每一个的示例数据(例如最多 10 行),然后您希望从这些表中得到什么结果。然后我们将能够向您展示解决方案。请记住,SQL 与集合一起工作。在其他语言中,当您使用集合时,您需要一个循环。您不需要 SQL 中的循环来处理集合。
  • 另外,您的示例没有意义——例如ON ST.WAY=SC.WAY——根据您发布的链接,WAY 不是这些表中的列。
  • 我正在努力,给我一些时间
  • 你是对的霍根。我已经改了。

标签: sql for-loop while-loop case


【解决方案1】:

先试试这个 SP,EXEC CheckOverSpeed 1 用于获取方式 1 的总数,其他方式相同,如果您需要自动获取所有方式的列表,请告诉我,但我能想到的第一件事正在使用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

【讨论】:

  • 为您解答!我现在就试试你的解决方案,
  • 让我更新它是否有效,因为我没有你的表,如果你有任何错误,请告诉我,以便我调试 xD
  • 我删除了SP最后部分多余的@,请检查
  • 但我从未使用过程序。如何检查是否存储了正确的值?
  • hmm,有些地方出错了,应该弹出一个值而不是'命令成功完成',让我先检查一下
【解决方案2】:

首先,这不是一个好的表结构。如果要存储此类数据,最好创建另一个键并将amount_drivers 列存储为多行中的单个列。 SPEED_CAT 也是如此。事实上,没有太多理由使用SPEED_CATEGORIES 表,因为您有固定数量的列。但是,为了以防这些值发生变化,我在下面使用了它们。

其次,这是我可以从您的结构和所需的输出中收集到的最好的结果,而无需数据支持。请参阅有关您问题的 cmets。

select
    Trf.ID,
    (
        case when Spd.MAX_SPEED <= Cat.SPEED_CAT_1 then Trf.amount_drivers1 else 0 end
        + case when Spd.MAX_SPEED <= Cat.SPEED_CAT_2 then Trf.amount_drivers2 else 0 end
        + case when Spd.MAX_SPEED <= Cat.SPEED_CAT_3 then Trf.amount_drivers3 else 0 end
        + case when Spd.MAX_SPEED <= Cat.SPEED_CAT_4 then Trf.amount_drivers4 else 0 end
        + case when Spd.MAX_SPEED <= Cat.SPEED_CAT_5 then Trf.amount_drivers5 else 0 end
        + case when Spd.MAX_SPEED <= Cat.SPEED_CAT_6 then Trf.amount_drivers6 else 0 end
        + case when Spd.MAX_SPEED <= Cat.SPEED_CAT_7 then Trf.amount_drivers7 else 0 end
        + case when Spd.MAX_SPEED <= Cat.SPEED_CAT_8 then Trf.amount_drivers8 else 0 end
        + case when Spd.MAX_SPEED <= Cat.SPEED_CAT_9 then Trf.amount_drivers9 else 0 end
        + case when Spd.MAX_SPEED <= Cat.SPEED_CAT_10 then Trf.amount_drivers10 else 0 end
    ) TO_HARD
from
    TRAFFIC Trf
    join MAX_SPEED Spd Trf.MAX_SPEED_KEY = Spd.ID
    join SPEED_CATEGORIES Cat on Trf.SPEED_CATEGORIE_KEY = Cat.ID

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-22
    • 1970-01-01
    • 2014-09-27
    • 2021-10-26
    相关资源
    最近更新 更多