24

例を使用して説明しようとする一般的な質問があります。

「id」、「name」、「category」、「appearance」、「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

私が受け取った2つの答え(どれも完全ではなかったので、私は自分で書いた)に続いて、私が最終的にしたことは次のとおりです。

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 に答える