Sql 查询Oracle以消除0数量
我有下一个查询,有时对于相同的id、客户和名称,我会得到一个带有数量的市场价值和另一个带有数量0的市场价值。如何修改查询以仅获取数量为的市场价值,而不获取数量为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') = ?
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行非零市场价值,我需要保留这两行。我已经编辑了问题,并输入了新的输出。