2

私はこのように3つのテーブルを設定しています(少し単純化されています):

time_tracking:id、tr_proj_id、tr_min、tr_type
time_projects:id、project_name
time_tasks:id、task_name

基本的に、値が「project」または「task」のtr_typeに基づいてproject_nameまたはtask_nameのいずれかを取得したい

時間追跡

+----+------------+--------+---------+
| id | tr_proj_id | tr_min | tr_type |
+----+------------+--------+---------+
|  1 |          3 |     60 | project |
|  2 |          3 |    360 | task    |
|  3 |          1 |    120 | project |
|  4 |          2 |     30 | project |
|  5 |          2 |     30 | task    |
|  6 |          1 |     90 | task    |
+----+------------+--------+---------+

time_projects

+----+------------------------+
| id |      project_name      |
+----+------------------------+
|  1 | Make someone happy     |
|  2 | Start a project        |
|  3 | Jump out of the window |
+----+------------------------+

time_tasks

+----+---------------------+
| id |      task_name      |
+----+---------------------+
|  1 | drink a beer        |
|  2 | drink a second beer |
|  3 | drink more          |
+----+---------------------+

必要な出力

+----+------------------------+------------+--------+---------+
| id |          name          | tr_proj_id | tr_min | tr_type |
+----+------------------------+------------+--------+---------+
|  1 | Jump out of the window |          3 |     60 | project |
|  2 | drink more             |          3 |    360 | task    |
|  3 | Make someone happy     |          1 |    120 | project |
|  4 | Start a project        |          2 |     30 | project |
|  5 | drink a second beer    |          2 |     30 | task    |
|  6 | drink a beer           |          1 |     90 | task    |
+----+------------------------+------------+--------+---------+

そして、JOIN全体が本当に悪いので、これまでに思いついたのはこれだけです(これは機能しません..):

SELECT tt.tr_proj_id, tt.tr_type, tt.tr_min, pp.project_name, pp.id, ta.task_name, ta.id
FROM time_tracking as tt, time_projects as pp, time_tasks as ta 
WHERE ((tt.tr_type = 'project' AND pp.id = tt.tr_proj_id) OR (tt.tr_type = 'task' AND ta.id = tt.tr_proj_id)) 
AND tt.tr_min > 0
ORDER BY tt.tr_proj_id DESC

誰かがこれを行う方法についてアイデアを持っているなら、気軽に共有してください!


更新:アクセスデータベースを使用していることを指定するのを忘れたようです。どうやらこれはやのようなものを受け入れないようCASEですcoalesce..どうやらありますIIF()が、この場合の使用方法についてはよくわかりません。

4

4 に答える 4

2

句を使用joinして、結合条件をwhere句から句に移動しますon

SELECT
    tt.tr_proj_id,
    tt.tr_type,
    tt.tr_min,
    pp.project_name,
    pp.id,
    ta.task_name,
    ta.id
FROM time_tracking as tt
left join time_projects as pp on tt.tr_type = 'project' AND pp.id = tt.tr_proj_id
left join time_tasks as ta on tt.tr_type = 'task' AND ta.id = tt.tr_proj_id
WHERE tt.tr_min > 0
ORDER BY tt.tr_proj_id DESC,tt.tr_day ASC

私はを使用しましleft joinた。これは、結合用の行が存在しない場合でもメインテーブルから行を取得します(結合がない場合は、結合されたテーブルの列からnullを取得します)


ここで重要な点は、多くのSQLプログラマーが気付いていないことですが、ON(この例のように)結合されたテーブルからのものでなくても、句には任意の条件が含まれる可能性があります。多くのプログラマーは、条件は正式な外部キー関係に関連する条件のみでなければならないと想定しています。

于 2012-11-22T19:02:08.747 に答える
0

2つの結合で結合を実行します。

select tt.id, tp.project_name name, tt.tr_proj_id, tt.tr_min, tt.tr_type
  from time_tracking tt
       inner join time_projects tp on tp.id = tt.tr_proj_id
 where tt.tr_type = 'project'
union all
select tt.id, tp.project_name name, tt.tr_proj_id, tt.tr_min, tt.tr_type
  from time_tracking tt
       inner join time_tasks tk on tk.id = tt.tr_proj_id
 where tt.tr_type = 'task'

それはあなたが望む正確なテーブルの結果を与えるでしょう

于 2012-11-22T19:05:00.440 に答える
0
SELECT
    time_tracking.id,
    time_tracking.tr_min,
    time_tracking.tr_type,
    coalesce(time_projects.project_name, time_tasks.task_name) as name
FROM time_tracking
LEFT OUTER JOIN time_projects on time_projects.id = time_tracking.tr_proj_id AND time_tracking.tr_type = 'project'
LEFT OUTER JOIN time_tasks on time_tasks.id = time_tracking.tr_proj_id AND time_tracking.tr_type = 'task'
WHERE time_tracking.tr_min > 0
ORDER BY time_tracking.id DESC -- ...

coalesceMSSQLでありISNULL、他のデータベーステクノロジに相当するものがあります

アイデアは、テーブルに結合し、結合が失敗した場合、結合が失敗NULLした場所を取得することです。次に、を使用COALESCEして、成功した結合値を選択します。

于 2012-11-22T19:07:11.810 に答える
0

これを試して:

SELECT
    tt.id,
    CASE WHEN tt.tr_type = 'project' THEN pp.project_name
         WHEN tt.tr_type = 'task' THEN ta.task_name END as name,
    tt.tr_proj_id,
    tt.tr_type,
    tt.tr_min,
FROM time_tracking as tt
   left join time_projects as pp on pp.id = tt.tr_proj_id
   left join time_tasks as ta on ta.id = tt.tr_proj_id
WHERE tt.tr_min > 0
ORDER BY tt.tr_proj_id DESC
于 2012-11-22T19:15:51.550 に答える