Sql 查询Oracle以消除0数量

Sql 查询Oracle以消除0数量,sql,oracle,Sql,Oracle,我有下一个查询,有时对于相同的id、客户和名称,我会得到一个带有数量的市场价值和另一个带有数量0的市场价值。如何修改查询以仅获取数量为的市场价值,而不获取数量为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') = ?

我有下一个查询,有时对于相同的id、客户和名称,我会得到一个带有数量的市场价值和另一个带有数量0的市场价值。如何修改查询以仅获取数量为的市场价值,而不获取数量为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
ID_CLIENT   CLIENT  NAME    MARKET_VALUE
207        Momentum AAA 3514.11
207        Momentum BBB 0
207        Momentum CCC 84289.84
如何修改查询以仅获取数量为的市场价值,而不获取数量为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'
这在SQL中是非常直接和简单的

market_value > 0
只有当您有空值时才需要NVL

NVL(market_value, 0) > 0
您的代码还存在多个其他问题:

截止日期“DD/MM/YYYY”=

永远不要使用字符来比较日期。正确的方法是让date列保持原样,并在R.H.S.上使用to_date将文本转换为date

通过查询,您将最终将字符串与?的占位符中的值的任何数据类型进行比较?。但是,在与日期进行比较时,应保持日期数据类型不变

和NVL h.类型,不在“主”中

和NVL h.仪器,不在“FX”中

这在语法上是不正确的。IN和NOT IN表达式必须用括号括起来

事实上,在您的情况下,您根本不需要In操作符。只需使用EQUAL=运算符

和NVL h型

另一个问题,

在Oracle中,和NULL被认为是类似的。这意味着,长度为零的字符串被视为空值

<>所以,你的表达就像说,把NULL当作空来和一个真实的值比较。这永远是错误的

更新

根据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
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

您只需将MAX与GROUP BY一起用作聚合函数。

您需要环顾其他行,并在且仅当另一行不存在时丢弃零市值:

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
)

我在比较中使用了not equal,尽管我认为您的所有值可能都是非负的。

所以听起来您需要计算每个组的最大市场价值是否为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);

注意:从上面的结果可以看出,如果有多行的市场价值为0,您将看到所有行;我想可以吗?

您的查询没有名为quantity的列注意:我没有投反对票。此外,INs在语法上不正确,因此这是无法运行的查询。添加和h.MARKET_值0是否不起作用?这不需要h.MARKET_值的附加谓词吗!=0? 还有,你为什么要做NVL?Oracle中没有空字符串。你所做的相当于说if为null,然后用null替换它,这样做没有任何意义。to_CHAR h.DATE,'DD/MM/YYYY'=?我也很担心。你为什么要这么做?保持日期不变,在R.H.S.上比较时使用日期。当我说数量时,我指的是市场价值谢谢你的回答。但是,如果每组有2行非零市场价值,我需要保留这两行。我已经编辑了问题,并输入了新的输出。