次のように、2 行の仮想テーブルへのクロス結合を使用してplayer_*
列のピボットを解除し、結果をグループ化できます。
SELECT
player,
COUNT(*) AS total_count
FROM (
SELECT
CASE WHEN x.is_in THEN t.player_in ELSE t.player_out END AS player
FROM mytable t
CROSS JOIN (SELECT TRUE AS is_in UNION ALL SELECT FALSE) x
) s
GROUP BY
player
;
つまり、元のテーブルのすべての行は基本的に複製され、派生テーブルの列がまたはであるかどうplayer_in
かに応じて、行の各コピーが または を提供して、単一の列を形成します。このピボット解除の方法は、@Bohemian によって提案された UNION メソッドよりもパフォーマンスが優れている可能性があります。これは、(物理) テーブルが 1 回だけ渡されるためです (ただし、両方の方法をテストして比較し、このアプローチに実質的な利点があるかどうかを判断する必要があります)。あなたの特定の状況)。player_out
is_in
TRUE
FALSE
player
上記の回答に対するコメントの1つで要求したように、インとアウトのカウントを計算するには、私の元の提案を次のように拡張できます。
SELECT
player,
COUNT( is_in OR NULL) AS in_count,
COUNT(NOT is_in OR NULL) AS out_count,
COUNT(*) AS total_count
FROM (
SELECT
x.is_in,
CASE WHEN x.is_in THEN t.player_in ELSE t.player_out END AS player
FROM mytable t
CROSS JOIN (SELECT TRUE AS is_in UNION ALL SELECT FALSE) x
) s
GROUP BY
player
;
ご覧のとおり、派生テーブルはis_in
独自の列を追加で返します。この列は、プレイヤーが出入りした回数をカウントするための 2 つの条件付き集計で使用されます。(興味のある方はここでOR NULL
裏技を解説しています。)
エントリをのように書き換えることもできます。それは確かに両方の式を短くします。また、より明確でエレガントなカウント方法を見つける人もいます. どちらの場合でも、パフォーマンスに違いはない可能性が高いので、好みに合わせて選択してください。COUNT(condition OR NULL)
SUM(condition)
SUM
2 番目のクエリの SQL Fiddle デモは、ここにあります。