24

我有一个通用问题,我将尝试用一个例子来解释。

假设我有一个包含以下字段的表格:“id”、“name”、“category”、“appearances”和“ratio”

这个想法是我有几个项目,每个项目都与一个类别相关并且“出现”了几次。比率字段应包括每个项目的出现占类别中项目出现总数的百分比。

在伪代码中,我需要的是以下内容:

  • 对于每个类别
    ,找到与其相关的项目的出现总和。例如,可以使用 ( select sum("appearances") from table group by category)

  • 对于每个项目
    ,将比率值设置为项目的外观除以为上述类别找到的总和

现在我试图用一个更新查询来实现这一点,但似乎做不到。我认为我应该做的是:

update Table T    
set T.ratio = T.appearances /   
(    
select sum(S.appearances)    
from Table S    
where S.id = T.id    
)

但是 MySQL 不接受 update 列中的别名 T,我没有找到其他方法来实现这一点。

有任何想法吗?

4

3 回答 3

57

根据我收到的两个答案(都不完整,所以我自己写了),我最终做了如下:

UPDATE Table AS target
INNER JOIN 
(
select category, appearances_sum
from Table T inner join (
    select category as cat, sum(appearances) as appearances_sum
    from Table
    group by cat
) as agg
where T.category  = agg.cat
group by category
) as source
ON target.category = source.category
SET target.probability = target.appearances / source.appearances_sum 

它的工作速度非常快。我也尝试过使用相关子查询,但速度要慢得多(数量级),所以我坚持使用连接。

于 2009-05-10T03:39:30.810 回答
6

在 UPDATE 之后立即使用连接: 参考手册 – 13.2.11 UPDATE 语法

所以 UPDATE table1 inner join table2 on .... set table1.foo=value where table2.bla = someothervalue

有了这些东西,总是看手册。MySql 有一个适当的参考手册,因此获得正确的语法应该不难;)

于 2009-05-09T08:35:08.193 回答
2

在mssql中是这样做的,我觉得mysql是一样的或者类似的:

create table T (id int, ratio float, appearances int)
insert T values (1, null, 2)
insert T values (1, null, 3)

update T
set ratio = cast(appearances as float)/ agg.appearancesSum
from T join (
    select id, sum(appearances) as appearancesSum
    from T
    group by id
) as agg on t.id = agg.id
于 2009-05-08T14:13:50.367 回答