代码之家  ›  专栏  ›  技术社区  ›  Haravikk

在何处启用重复项?

  •  3
  • Haravikk  · 技术社区  · 8 年前

    我想使用一个简单的查询来减少表中的值,如下所示:

    UPDATE `Table`
    SET `foo` = `foo` - 1
    WHERE `bar` IN (1, 2, 3, 4, 5)
    

    这在上面这样的例子中非常有效,其中 IN 列表只包含唯一的值,因此每个匹配的行都有其 foo 列递减1。

    问题是当列表包含重复项时,例如:

    UPDATE `Table`
    SET `foo` = `foo` - 1
    WHERE `bar` IN (1, 3, 3, 3, 5)
    

    在这种情况下,我想排在 bar 是 3 减三倍 1 和 5 减去1。

    有没有一种方法可以改变行为,或者我可以使用另一种查询来获得所需的行为?

    我特别使用mysql 5.7,以防有任何特定于mysql的解决方法是有用的。

    更新 :我正在用脚本语言构建查询,因此可以在运行查询之前提供执行任何附加处理的解决方案(可能是伪代码,以便尽可能多地使用?)。我不介意这样做,我只想让查询尽可能简单,同时给出预期的结果。

    3 回复  |  直到 8 年前
        1
  •  1
  •   Uueerdo    8 年前

    如果可以先处理原始列表以获取计数,则可以动态构造此类查询:

    UPDATE `Table`
    SET `foo` = `foo` - CASE `bar` WHEN 1 THEN 1 WHEN 3 THEN 3 WHEN 5 THEN 1 ELSE 0 END
    WHERE `bar` IN (1, 3, 5)
    ;
    

    注意:其他的只是彻底的/偏执的;应该在哪里阻止它走那么远。

        2
  •  0
  •   Eray Balkanli    8 年前

    有一个例子可能对您的目的有益:

    create table #temp (value int)
    create table #mainTable (id int, mainValue int)
    
    insert into #temp (value) values (1),(3),(3),(3),(4)
    insert into #mainTable values (1,5),(2,5),(3,5),(4,5)
    
    select value,count(*) as AddValue
    into #otherTemp
    from #temp t
    group by value
    
    update m
    set mainValue = m.mainValue+ ot.AddValue
    from #otherTemp ot
    inner join #mainTable m on m.id=ot.value
    
    select * from #mainTable
    
        3
  •  0
  •   Gordon Linoff    8 年前

    这有点棘手,但可以先聚合:

    update table t join
           (select bar, count(*) as factor
            from (select 1 as bar union all select 3 as bar union all select 3 as bar union all select 3 as bar union all select 5
                 ) b
           ) b
           on t.bar = b.bar
        t.foo = t.foo - bar.factor;