4

以下のような3つのテーブルがあります。

テスト

    +--------------+--------+
    | Test_Case_ID | Status |
    +--------------+--------+
    |           10 | PASS   |
    |           20 | FAIL   |
    |           30 | FAIL   |
    +--------------+--------+

欠陥

    +-----------+
    | Defect_ID |
    +-----------+
    |       500 |
    |       400 |
    +-----------+

およびlink1

    +--------------+-----------+
    | Test_Case_ID | Defect_ID |
    +--------------+-----------+
    |           20 |       500 |
    |           30 |       500 |
    |           30 |       400 |
    +--------------+-----------+

私は以下のクエリを試しています

select 
test.test_case_id,
test.status,
case when test.status = 'FAIL' then 
(select link1.defect_id 
from link1 
where 
test.test_case_id = link1.test_case_id) 
end as defect1_id
from test test

次のエラーが発生します。「エラー12/20/201210:05:17AM 0:00:00.093データアナリストのToad:ORA-01427:単一行のサブクエリが複数の行を返す178」

リンクテーブルから「30」の両方のレコードを取得する方法はありますか?テストケース30が欠陥500と400のために失敗していることを表示したいからです。

本当にありがとう

4

2 に答える 2

4

リンク テーブルには、値が "30" の行が 2 つあります。これはあなたの問題です。

これらの行のどれが必要ですか?

サブクエリを修正するには、句に言うselect max(link1.defect_id)か追加することができます。and rownum = 1where

あなたが望むのは、おそらくもっと複雑です。欠陥を文字列に連結するこのバージョンはどうですか。

select t.test_case_id, t.status,
       listagg(cast(l.defect_id as varchar(32)) within group (order by l.defect_id) as defects
from test t left join
     link1 l
     on t.test_case_id = l.test_case_id
group by t.test_case_id, t.status

Oracle のバージョンは指定しません。が利用できない場合listaggは、wm_concatおそらく利用可能です。 これは、Oracle の集計で文字列を連結するさまざまな方法に関するリファレンスです。

于 2012-12-20T15:10:54.440 に答える
3

JOINサブクエリの代わりにa を使用することを考えましたか:

select 
  t.test_case_id,
  t.status,
  case when t.status = 'FAIL' then l.defect_id  
    end as defect1_id
from test t
left join link1 l
  on t.test_case_id = l.test_case_id

デモで SQL Fiddle を参照してください

これにより両方のレコードが返され、最終結果でどちらのアイテムを返すかを決定できます。

結果:

| TEST_CASE_ID | STATUS | DEFECT1_ID |
--------------------------------------
|           20 |   FAIL |        500 |
|           30 |   FAIL |        500 |
|           30 |   FAIL |        400 |
|           10 |   PASS |     (null) |

コメントに基づいて、Oracle 11g を使用している場合は、LISTAGG()関数を使用してレコードを 1 つの行に結合できます。

select 
  t.test_case_id,
  t.status,
  case 
    when t.status = 'FAIL' 
    then listagg(l.defect_id, ', ')
          within group (order by l.defect_id)
  end as defect1_id
from test t
left join link1 l
  on t.test_case_id = l.test_case_id
group by t.test_case_id, t.status

デモで SQL Fiddle を参照してください

結果:

| TEST_CASE_ID | STATUS | DEFECT1_ID |
--------------------------------------
|           10 |   PASS |     (null) |
|           20 |   FAIL |        500 |
|           30 |   FAIL |   400, 500 |
于 2012-12-20T15:12:58.467 に答える