2017-04-24 14 views
0

CASEが一致を見つけたら、最初の一致を壊して返します。しかし、私はすべてとケースステートメントから一致しています。例えばOracle複数のCASE文が真であると評価する

select distinct PERSON, 
       LOCATION, 
       (case 
        when LOCATION = 'CA' and PHONE is not null 
        then PHONE 
        when LOCATION = 'NY' and PHONE is not null 
        then PHONE 
        when LOCATION = 'FL' and PHONE is not null 
        then PHONE 
        when LOCATION = 'MA' and PHONE is not null 
        then PHONE 
        else '---' 
       end) 
from DIRECTORY 
where LOCATION in 
    ('CA', 'NY', 'FL', 'MA'); 

人がそれぞれの状態にある電話番号を持つことができますので、私がしたいことは基本的に状態の順序によって「ランクさ」が見つかり最初電話番号、です。私が得ているのは、見つかったすべての電話番号です。あなたは、サブクエリ内の各状態に順位を割り当て、その後、それぞれの人のための最高位記録を保持でき

答えて

2

Thxを...:従うこと

WITH cte1 AS (
    SELECT 
     PERSON, 
     LOCATION, 
     PHONE, 
     CASE WHEN LOCATION = 'CA' AND PHONE IS NOT NULL THEN 1 
      WHEN LOCATION = 'NY' AND PHONE IS NOT NULL THEN 2 
      WHEN LOCATION = 'FL' AND PHONE IS NOT NULL THEN 3 
      WHEN LOCATION = 'MA' AND PHONE IS NOT NULL THEN 4 
      ELSE 5  -- the NULL case 
     END AS LOCATION_RANK 
    FROM DIRECTORY 
    WHERE LOCATION IN ('CA', 'NY', 'FL', 'MA') 
), 
cte2 AS (
    SELECT t.*, 
      ROW_NUMBER() OVER (PARTITION BY t.PERSON ORDER BY t.LOCATION_RANK) rn 
    FROM cte1 t 
) 
SELECT 
    t.PERSON, 
    t.LOCATION, 
    COALESCE(t.PHONE, '---') 
FROM cte2 t 
WHERE t.rn = 1 
+0

ありがとう - それは私が行方不明だった第2のcteだった。最初のcteからmax(LOCATION_RANK)のようなものを取得しようとしていましたが、それでもすべての行が返されました。これは素晴らしいことです - ありがとうございます... – user1628169

0

TimBielgeleisenのCTEアプローチ@は容易であろうそして維持するが、あなたはケースの表現を繰り返しているが、あなたは、keep dense_rankを使用して、任意のCTEはなく、同じことを行うことができます:

select person, 
    min(location) keep (dense_rank first order by 
    case when phone is null then 2 else 1 end, 
    case location when 'CA' then 1 when 'NY' then 2 when 'FL' then 3 
     when 'MA' then 4 end) as location, 
    coalesce(min(phone) keep (dense_rank first order by 
    case when phone is null then 2 else 1 end, 
    case location when 'CA' then 1 when 'NY' then 2 when 'FL' then 3 
     when 'MA' then 4 end), '---') as phone 
from directory 
where location in ('CA', 'NY', 'FL', 'MA') 
group by person; 

たりできMOをそれらのメンテナンス性の向上のために、単一のCTEまたはインライン・ビューにcase式(S)VEの:あなたはまだ一度これらのアプローチのいずれかのテーブルをヒットしている

select person, 
    min(location) keep (dense_rank first order by phone_rank, location_rank) as location, 
    coalesce(min(phone) keep (dense_rank first order by phone_rank, location_rank), 
    '---') as phone 
from (
    select person, location, phone, 
    case location when 'CA' then 1 when 'NY' then 2 when 'FL' then 3 
     when 'MA' then 4 end as location_rank, 
    case when phone is null then 2 else 1 end as phone_rank 
    from directory 
    where location in ('CA', 'NY', 'FL', 'MA') 
) 
group by person; 

、順位は少しだけ異なる方法で処理され、パフォーマンスの差は期待できません(ただし、実際のデータで確認するのが最善です)。

関連する問題