0

単純なテーブルに次のデータがあります。

ID | TYPE
---------
1  | 1
1  | 2
2  | 1
3  | 2
4  | 1
4  | 2
4  | 3
5  | 1
5  | 3
6  | 3

次の方法でこのデータをクエリする必要があります。

  • ID ごとに 1 行のみを返す必要があります
    • ID の行が 1 つしかない場合は、それを返します。
    • ID の行が複数ある場合は、TYPE = 2 の行を返します。存在しない場合は、TYPE = 3 の行を返します。
  • TYPE は 1、2、または 3 のいずれかです
  • ID と TYPE には複合一意インデックスがあります。つまり、ID ごとに最大 3 つの行が存在する可能性があります。

質問: このロジックをクエリにどのように配置しますか?


期待される結果:

ID | TYPE
---------
1  | 2
2  | 1
3  | 2
4  | 2
5  | 3
6  | 3
4

8 に答える 8

2

別のアプローチでは、分岐時にケースを最小限に抑えます:http ://www.sqlfiddle.com/#!4/9957d/17

select id, 

    coalesce( sum(case when type=2 then 2 end), max(type) ) as type

from tbl
group by id
order by id

出力:

| ID | TYPE |
-------------
|  1 |    2 |
|  2 |    1 |
|  3 |    2 |
|  4 |    2 |
|  5 |    3 |
|  6 |    3 |
于 2012-08-20T15:30:03.373 に答える
2

Oracle は最近のすべてのバージョンで分析関数を備えています。

WITH
  sequenced AS
(
  SELECT
    *,
    ROW_NUMBER() OVER (PARTITION BY id
                           ORDER BY CASE type WHEN 2 THEN 1
                                              WHEN 3 THEN 2
                                              WHEN 1 THEN 3 END) AS sequenced_id
  FROM
    yourTable
)
SELECT
  *
FROM
  sequenced
WHERE
  sequence_id = 1

この手法を使用すると、PrimaryKey と検索値だけでなく、テーブル内のすべての値が返されます。

編集:

これに対処する最善の方法は、各タイプの優先順位を持つ別のテーブルを用意することです。

 type | preference_value
------+------------------
  2   |         1
  3   |         2
  1   |         3

これ2は、最優先、32 番目の優先、13 番目の優先であると述べています。

CASEしかし、少人数だからこそ、簡単な言葉でできることもあります。上記の修正されたクエリを参照してください。

于 2012-08-20T15:00:17.600 に答える
2

ここに私の意見があります: http://www.sqlfiddle.com/#!4/9957d/4

select id, 
    case when sum(case when type = 2 then 1 end) = 1 then
       2
    else
       max(type)
    end   
from tbl
group by id
order by id

出力:

| ID | TYPE |
-------------
|  1 |    2 |
|  2 |    1 |
|  3 |    2 |
|  4 |    2 |
|  5 |    3 |
|  6 |    3 |
于 2012-08-20T15:16:08.793 に答える
1

TYPE2 より大きい値がないことがわかっているので、次のようにするだけです。

select ID, max(TYPE) as TYPE
from MyTable
group by ID
于 2012-08-20T14:58:59.850 に答える
1

これを試して

select id, type from
(
   select *, ROW_NUMBER() over (partition by id order by abs(2.25-type) ) as rn
   from yourtable
)v
where rn=1
于 2012-08-20T15:06:34.527 に答える
1

私は少しハックを使用します。

SELECT ID, IF(SUM(TYPE) IN (5, 6), 2, MAX(TYPE)) AS TYPE
FROM table
GROUP BY ID
于 2012-08-20T15:11:59.890 に答える
1

関数を楽しむMOD()

SELECT 
    id,
    MOD(MIN(MOD(type+1,3))+1,3)+1 AS type
FROM
    tableX
GROUP BY
    id ;
于 2012-08-20T15:22:04.540 に答える
0

podiluskaとDemsによる提案に基づいて、私は現在これを使用しています:

with type_order as
(
    select 1 as type, 0 as prio from dual
    union all
    select 2 as type, 2 as prio from dual
    union all
    select 3 as type, 1 as prio from dual
)
select id, type from 
( 
   select yt.*, ROW_NUMBER() over (partition by id order by o.prio desc) as rn 
   from yourtable yt
   inner join type_order o on yt.type = o.type
)v 
where rn=1 

これは非常に意図を明らかにするものであり、拡張するのは簡単です。将来さらにタイプが増える場合は、このtype_orderインラインビューを実際のテーブルにリファクタリングできます。

于 2012-08-20T15:29:00.660 に答える