3

3 つのテーブルのすべての子の数を取得するために、1 つ (または 2 つまたは 3 つ) のクエリを処理しようとして、私の午後はすべて費やされました。私のデザインを見てください:

ユーザーテーブル

id_user | name
1 | foo
2 | bar

ウォンテーブル

id_won | user
1 | 1
2 | 1
3 | 2

テーブルを描画します

id_draw | user
1 | 1
2 | 2
3 | 2

テーブルを失います

id_lose | user
1 | 1
2 | 1
3 | 1

私はこのようなものを取得しようとしています:

name | wons | draws | loses
foo | 2 | 1 | 3
bar | 1 | 2 | 0

これは私の試みです:

select 
    u.name, w.total_w, d.total_d, l.total_l
from 
    user u
    LEFT JOIN 
    (select count(user) as total_w, user from wons group by user) as w
    ON w.user = u.id_user
    LEFT JOIN 
    (select count(user) as total_d, user from draws group by user) as d 
    ON d.user = w.user
    LEFT JOIN 
    (select count(user) as total_l, user from loses group by user) as l 
    ON d.user= .user

group by u.id_user;
4

4 に答える 4

3

サブクエリでそれらの合計値を計算し、テーブルに結合できますusers。他のテーブルに存在しない場合の代わりにCOALESCE表示するように追加しました。zeronulluser

SELECT  a.id_user,
        COALESCE(b.totalWon,0) Wons,
        COALESCE(d.totalLoses,0) Loses,
        COALESCE(c.totalDraws,0) Draws
FROM    users a
        LEFT JOIN 
        (
            SELECT `user`, COUNT(id_won) totalWon
            FROM wons
            GROUP BY `user`
        ) b ON a.id_user = b.`user`
        LEFT JOIN
        (
            SELECT `user`, COUNT(id_draw) totalDraws
            FROM draws
            GROUP BY `user`
        ) c ON a.id_user = c.`user`
        LEFT JOIN
        (
            SELECT `user`, COUNT(id_lose) totalLoses
            FROM loses
            GROUP BY `user`
        ) d ON a.id_user = d.`user`

SQLFiddle デモ

于 2012-09-29T01:28:22.823 に答える
2

最もクリーンな SQL は次のとおりです。

SELECT 
    u.name,
    w.wins,
    d.draws,
    l.loses
FROM
    user u
LEFT JOIN 
    (SELECT user,COUNT(*) wins FROM wons GROUP BY user) w ON w.user = u.id_user
LEFT JOIN 
    (SELECT user,COUNT(*) draws FROM draws GROUP BY user) d ON d.user = u.id_user
LEFT JOIN 
    (SELECT user,COUNT(*) loses FROM loses GROUP BY user) l ON l.user = u.id_user

http://sqlfiddle.com/#!2/91b61/10を参照してください。

于 2012-09-29T01:45:13.790 に答える
2
select u.name, w.uw as wins, l.ul as loses, d.ud as draws from user
    left join (select user, COUNT(id_won) uw from wons group by user) w on w.user = u.user_id
    left join (select user, COUNT(id_lose) ul from loses group by user) l on l.user = u.user_id
    left join (select user, COUNT(id_draw) ud from draws group by user) d on d.user = u.user_id

これは、タスクに必要な作業量だけです。

于 2012-09-29T01:31:01.420 に答える
0

プロジェクトにとってやり過ぎかもしれませんが、望ましい結果をたくさん生成する場合は、パフォーマンスを念頭に置いた別のアプローチを提案します。

要約テーブルを作成します (目的の出力に似ています)。そこで各ユーザー用に作成されたシェル レコードを空にすることができます。

サマリー テーブルのデータを単純に更新するトリガーを、勝ち、引き分け、および損失のテーブルに追加します。

それが一つのアプローチです。次のアプローチは、目的の結果がミッション クリティカルではない場合 (つまり、最新のものである必要がない場合)、スケジュールされたイベント (上記のクエリを実行する 10 分または 20 分ごとに実行されるイベント) を追加することを検討することです (これは私が調べたものです)。 +1 票が与えられた場合)、それを使用してサマリー テーブルを更新します。

頑張ってください!

于 2012-09-29T01:40:03.507 に答える