27

映画俳優の名前と彼らが出演した映画を含む正規化されていないテーブルがあるとします。

CREATE TABLE movies_actors (
  movies_actors_id INT,
  movie VARCHAR(255),
  actor VARCHAR(255),
  PRIMARY KEY (movies_actors_id)
);

私は を実行して、SELECT actor, COUNT(1) FROM movies_actors GROUP BY actorその俳優が出演した映画の数を調べます。しかし、その俳優が出演した映画の割合も知りたいです。

私はこれを行うことができると思います:

SELECT
  actor,
  COUNT(1) AS total,
  COUNT(1) / (SELECT COUNT(1) FROM movies_actors) * 100 AS avg
FROM movies_actors
GROUP BY actor;

しかし、それはただのようです... idk...不愉快です。

何か案は?

4

5 に答える 5

36

大規模なセットの場合、サブクエリよりも JOIN の方がパフォーマンスが向上する場合があります。

SELECT ma.actor
     , COUNT(1) AS total
     , COUNT(1) / t.cnt * 100 AS `percentage`
  FROM movies_actors ma
 CROSS
  JOIN (SELECT COUNT(1) AS cnt FROM movies_actors) t
 GROUP
    BY ma.actor
     , t.cnt  

大規模なセットの場合、および行の大部分が返される場合、JOIN 操作は通常、サブクエリよりも優れたパフォーマンスを発揮します。あなたの場合、それは相関サブクエリではないため、MySQL はそれを複数回実行する必要がないため、違いはありません。

...のファンではない方への注意事項COUNT(1)... のすべての出現箇所を置き換えるか、COUNT(1)同等COUNT(*)IFNULL(SUM(1),0)結果を得ることができます。

于 2013-01-25T05:45:51.460 に答える
2

同じテーブルから操作されたデータを取得したいときはいつでも、自己交差結合を実行してください。

SELECT
m.actor,
COUNT(m.actor) AS total,
(COUNT(m.actor) / t.total_movies) * 100 AS avg
FROM movies_actors m
cross (select count(*) as total_movies from movies_actors) t
GROUP BY m.actor;
于 2013-01-25T05:57:18.317 に答える
0

それが「より良い」かどうかはわかりませんが、SUMを実行して他の場所で計算を行うことができます。

SELECT actor,
    COUNT(1) AS total,
    SUM(oneMoviePercentPts) AS percentage
FROM movies_actors
CROSS JOIN 
(
    SELECT 100 / CAST(COUNT(1) AS DECIMAL(15,4)) AS oneMoviePercentPts 
    FROM movies_actors
) t
GROUP BY actor

MySQLオプティマイザがサブクエリを複数回実行しないほど賢いことを願っていますが、結合構文によってそれが明示的になります。

于 2013-01-25T05:47:57.357 に答える