2015-10-14 2 views
-1

У меня есть следующий запрос, а иногда и для одного и того же идентификатора, клиентов и имени. Я получаю рыночную стоимость с количеством и другой рыночной стоимостью с количеством 0. Как я могу изменить запрос, чтобы получить только рыночная стоимость с количеством, а не количеством 0?Запрос на Oracle для устранения 0 количество

SELECT p.ID_CLIENT, p.CLIENT, p.NAME, h.MARKET_VALUE 
FROM HOLDING h 
INNER JOIN PORTFOLIO p ON h.PF_ID = p.PF_ID 
WHERE 
    TO_CHAR (h.DATE, 'DD/MM/YYYY') = ? 
    AND NVL (p.PF_ID, '') = ? 
    AND NVL (h.TYPE, '') NOT IN 'Master' 
    AND NVL (h.INSTRUMENT, '') NOT IN 'FX' 

Выход у меня сейчас:

ID_CLIENT CLIENT NAME MARKET_VALUE 
207  Momentum AAA 0 
207  Momentum AAA 3514.11 
207  Momentum BBB 0 
207  Momentum CCC 84289.84 
207  Momentum CCC 358.74 

И то, что я хочу это:

ID_CLIENT CLIENT NAME MARKET_VALUE 
207  Momentum AAA 3514.11 
207  Momentum BBB 0 
207  Momentum CCC 84289.84 
207  Momentum CCC 358.74 
+1

В вашем запросе нет столбца с именем 'количество' (примечание: я не сделал нисходящего). Кроме того, 'IN' синтаксически неверны, поэтому запрос не запускается. –

+0

Добавил ли 'AND h.MARKET_VALUE <> 0' не трюк? – dasblinkenlight

+0

Не нужен ли только дополнительный предикат 'h.market_value! = 0'? Кроме того, почему вы делаете 'NVL (...., '')'? В Oracle нет такой вещи, как пустая строка. То, что вы делаете, эквивалентно выражению «если имеет значение NULL, а затем заменить его на null», что на самом деле не имеет смысла делать. – Boneist

ответ

0

Как я могу изменить запрос, чтобы получить только рыночную стоимость с количеством а не количество 0?

Это довольно просто и просто в SQL.

market_value > 0 

Вам нужно NVL только тогда, когда у вас есть NULL значения.

NVL(market_value, 0) > 0 

Есть несколько других проблем с вашим кодом:

TO_CHAR (h.DATE, 'DD/MM/YYYY') =?

Никогда не принимал TO_CHAR чтобы сравнить даты. Правильный способ - указать столбец даты как есть, и использовать TO_DATE на R.H.S. для преобразования литерала в ДАТА.

С вашим запросом вы закончите сравнение STRING с любым типом данных, который у вас есть для значения в держателе места ?. Тем не менее, вы должны оставить DATE тип данных, так как он совпадает с датами.

И NVL (h.TYPE, '') NOT IN 'Мастер'

И NVL (h.INSTRUMENT, '') NOT IN 'FX'

Это синтаксически неверно , IN и НЕ В выражение должно быть заключено в пределах скобки.

Фактически, в вашем случае вам не нужен оператор IN. Просто используйте EQUAL= оператора.

И NVL (h.TYPE, '')

Другая проблема,

В Oracle '' и NULL считаются похожи. Это означает, что строка с нулевой длиной обрабатывается как значение NULL.

Итак, ваше выражение так же, как и выражение, рассмотрите NULL как NULL для сравнения с реальным значением. Который всегда будет FALSE.

UPDATE

на основе новых обновлений OP, как показано ниже:

Выход у меня сейчас:

ID_CLIENT CLIENT NAME MARKET_VALUE 
207  Momentum AAA 0 
207  Momentum AAA 3514.11 
207  Momentum BBB 0 
207  Momentum CCC 84289.84 

И то, что я хочу это:

ID_CLIENT CLIENT NAME MARKET_VALUE 
207  Momentum AAA 3514.11 
207  Momentum BBB 0 
207  Momentum CCC 84289.84 

Вам просто нужно использовать MAX как функцию агрегата вместе с GROUP BY.

+0

Спасибо за ваш ответ.Но если у меня есть 2 ненулевые строки market_value для каждой группы, мне нужно сохранить оба. Я отредактировал этот вопрос и поставил новый вывод. – abetitou

0

Вы должны смотреть вокруг в других строках и выбросить нулевой рыночную стоимость, если и только если другая строка не существует:

with q as (
    SELECT p.ID_CLIENT, p.CLIENT, p.NAME, h.MARKET_VALUE 
    FROM HOLDING h 
    INNER JOIN PORTFOLIO p ON h.PF_ID = p.PF_ID 
    WHERE /* I'll let you fix this part */ 
     TO_CHAR (h.DATE, 'DD/MM/YYYY') = ? 
     AND NVL (p.PF_ID, '') = ? 
     AND NVL (h.TYPE, '') NOT IN 'Master' 
     AND NVL (h.INSTRUMENT, '') NOT IN 'FX' 
) 
select * from q 
where MARKET_VALUE <> 0 or not exists (
    select 1 from q q2 
    where /* I'm not entirely sure if this is your primary key */ 
      q2.ID_VALUE = q1.ID_VALUE 
     and q2.CLIENT = q1.CLIENT 
     and q2.NAME = q.NAME 
     and q2.MARKET_VALUE <> 0 
) 

Я не использовал равный в сравнениях, хотя я полагаю, что все ваши значения, вероятно, неотрицательны.

0

Так звучит, как вам нужно работать, если максимальная рыночная стоимость для каждой группы 0 или нет, а затем процеживают соответственно, что-то вроде:

with sample_data as (select 207 id_client, 'Momentum' client, 'AAA' name, 0 market_value from dual union all 
        select 207 id_client, 'Momentum' client, 'AAA' name, 3514.11 market_value from dual union all 
        select 207 id_client, 'Momentum' client, 'BBB' name, 0 market_value from dual union all 
        select 207 id_client, 'Momentum' client, 'CCC' name, 84289.84 market_value from dual union all 
        select 207 id_client, 'Momentum' client, 'CCC' name, 358.74 market_value from dual union all 
        select 207 id_client, 'Momentum' client, 'DDD' name, 8289.24 market_value from dual union all 
        select 207 id_client, 'Momentum' client, 'DDD' name, 38.76 market_value from dual union all 
        select 207 id_client, 'Momentum' client, 'DDD' name, 0 market_value from dual union all 
        select 207 id_client, 'Momentum' client, 'EEE' name, 0 market_value from dual union all 
        select 207 id_client, 'Momentum' client, 'EEE' name, 0 market_value from dual), 
-- end of mimicking the results of your query 
      res as (select id_client, 
          client, 
          name, 
          market_value, 
          max(market_value) over (partition by id_client, name) max_market_value 
        from sample_data) 
select id_client, 
     client, 
     name, 
     market_value 
from res 
where max_market_value = 0 
or  (max_market_value != 0 and market_value != 0); 

ID_CLIENT CLIENT NAME MARKET_VALUE 
---------- -------- ---- ------------ 
     207 Momentum AAA  3514.11 
     207 Momentum BBB    0 
     207 Momentum CCC  84289.84 
     207 Momentum CCC  358.74 
     207 Momentum DDD  8289.24 
     207 Momentum DDD   38.76 
     207 Momentum EEE    0 
     207 Momentum EEE    0 

Это означает, что ваш запрос будет выглядеть примерно так:

select id_client, 
     client, 
     name, 
     market_value 
from (select p.id_client, 
       p.client, 
       p.name, 
       h.market_value, 
       max(h.market_value) over (partition by p.id_client, p.name) max_market_value 
     from holding h 
       inner join portfolio p on (h.pf_id = p.pf_id) 
     where h.date = to_date(:p_date_string, 'DD/MM/YYYY') 
     and p.pf_id = :p_pf_id 
     and nvl (h.type, '{NULL}') not in ('Master') 
     and nvl (h.instrument, '{NULL}') not in ('FX')) 
where max_market_value = 0 
or  (max_market_value != 0 and market_value != 0); 

NB Как видно из приведенных выше результатов, если бы было несколько строк с рыночной стоимостью 0, вы бы увидели их все; Я предполагаю, что все в порядке?

+0

это сработало. Большое спасибо :) – abetitou

Смежные вопросы