0

MySqlデータベースでは、少しトリッキーなクエリを実行する必要があります。2つの列(タイプ(プロジェクト、サポート、教育)と値(例では60と40))でのみ結果を取得する必要があります

タイプを含む静的テーブルがあります。

T1

ID  TYPE
1   PROJECT
2   PROJECT
3   PROJECT
4   SUPPORT
5   EDUCATION

いくつかのタイプの値を持つすべてのタスクを含む静的テーブルT2があります。

    T2

  TASK    T1ID

    1      1
    2      1
    3      2
    4      3 
    5      4
    6      5

T3は、いくつかのIDSで作成されたタスクの動的テーブルです。

T3 

ID
1
2
3
4
5
6

T4テーブルには、これらのタスクを作成した人の情報が含まれています。

T4

T3ID     Name
1       Bob Marley
2       Bob Marley
3       Bob Marley
4       Bob Marley
5       Tom Cruise
6       Bob Marley

最後に、T5にはT2とT3からの情報が含まれています

T5

TASK    T3ID
  1       1
  2       2
  3       3
  5       4
  1       5
  5       6

一部の特定の人(常に1人-この例ではBobMarleyまたはTomCruise)の場合、プロジェクト、サポート、または教育に取り組んだ人の数をパーセントで統計する必要があります。

そこで、ボブ・マーリーを選択します。彼のT3IDは1、2、3、4、6です。

表5では、彼のタスクIDは1、2、3、5、そして5です。

したがって、表T2を見ると、彼のT1 IDは1、1、2、4、および4です。これは、BobMarleyが3つのプロジェクトと2つのサポートタスクに取り組んだことを意味します。

したがって、Bob Marleyを選択すると、結果は次のようになります。

PROJECT  60
SUPPORT  40

これは、クエリの最終結果です。どうすればこれを達成できますか?いくつかのJOINステートメントである必要があり、もちろんWHERE句で使用できることを知っています。

where name='Bob Marley'

入れたら

 `where name=Tom Cruise

結果は

PROJECT 100`

ありがとうございました

4

1 に答える 1

4

私はこれがあなたが探しているものだと思います:

SELECT 
  t4.Name,
  SUM(CASE WHEN t1.type = 'PROJECT'   THEN 1 ELSE 0 END) * 100 / COUNT(t1.type) Project,
  SUM(CASE WHEN t1.type = 'SUPPORT'   THEN 1 ELSE 0 END) * 100 / COUNT(t1.type) SUPPORT,
  SUM(CASE WHEN t1.type = 'EDUCATION' THEN 1 ELSE 0 END) * 100 / COUNT(t1.type) Education
FROM T1
INNER JOIN T2 ON t1.ID = t2.T1ID
INNER JOIN t5 ON t2.task = t5.task
INNER JOIN t3 ON t3.id = t5.t3id
INNER JOIN t4 ON t3.Id = t4.t3id
GROUP BY t4.Name;

SQLフィドルデモ

これはあなたに与えるでしょう:

|       NAME | PROJECT | SUPPORT | EDUCATION |
----------------------------------------------
| Bob Marley |      60 |      40 |         0 |
| Tom Cruise |     100 |       0 |         0 |

投稿したサンプルデータの場合。

注:これによりName、プロジェクトとタスクに関係したものだけが表示されます。sをゼロに置き換えるために、タスクまたはプロジェクトに関与しなかったもの(一致しない行)を含めるOUTER JOIN(LEFT or RIGHT)代わりに、テーブルを作成する必要がある場合があります。INNER JOINNameIFNULL()NULL


アップデート:

この関数を使用CONCAT()してこれを行うことができますが、前のクエリをサブクエリ内に含め、次のように外部クエリでこれを行うと、より簡単で読みやすくなります。

SELECT
  Name,
  CONCAT(CAST(project   AS DECIMAL(10, 2)), ' AND ', 
         CAST(support   AS DECIMAL(10, 2)), ' AND ', 
         CAST(education AS DECIMAL(10, 2))) AS Percentage
FROM
(
  SELECT 
    t4.Name,
    SUM(CASE WHEN t1.type = 'PROJECT' THEN 1 ELSE 0 END) * 100 / COUNT(t1.type) Project,
    SUM(CASE WHEN t1.type = 'SUPPORT' THEN 1 ELSE 0 END) * 100 / COUNT(t1.type) SUPPORT,
    SUM(CASE WHEN t1.type = 'EDUCATION' THEN 1 ELSE 0 END) * 100 / COUNT(t1.type) Education
  FROM T1
  INNER JOIN T2 ON t1.ID = t2.T1ID
  INNER JOIN t5 ON t2.task = t5.task
  INNER JOIN t3 ON t3.id = t5.t3id
  INNER JOIN t4 ON t3.Id = t4.t3id
  GROUP BY t4.Name
) t;

更新されたSQLフィドルデモ

これはあなたに与えるでしょう:

|       NAME |               PERCENTAGE |
-----------------------------------------
| Bob Marley | 60.00 AND 40.00 AND 0.00 |
| Tom Cruise | 100.00 AND 0.00 AND 0.00 |

WHEREこの値をWHERE Name = 'Some name'、外部クエリやサブクエリなどの任意のユーザー名のみに制限する句を追加できます。


アップデート2

OK、すみません、それを逃しました。そのために動的SQLを実行する必要はありPIVOTません。CONCAT()あなたはそのようにこれを行うことができます:

SELECT 
  t1.type,
  COUNT(t2.task) * 100 / 
  (SELECT COUNT(*)
   FROM T4 t 
   WHERE t4.Name = t.Name) AS Percentage
FROM T1
INNER JOIN T2 ON t1.ID = t2.T1ID
INNER JOIN t5 ON t2.task = t5.task
INNER JOIN t3 ON t3.id = t5.t3id
INNER JOIN t4 ON t3.Id = t4.t3id
WHERE t4.Name = 'Bob Marley' 
GROUP BY t4.Name, t1.type;

更新されたSQLフィドルデモ

これはあなたに与えるでしょう:

|    TYPE | PERCENTAGE |
------------------------
| PROJECT |         60 |
| SUPPORT |         40 |
于 2013-01-05T13:51:12.477 に答える