ORA-01427: single-row subquery returns more than one row error comes after fetching some records - sql

My query is fetching records in sql developer. But when i run it from ksh file and spool it, partial records get generates and error comes. How can I find out the data for which this error is coming?
Query is:
select im.item as "ITEM",
(select val.uda_value_desc
from uda_values val,UDA_ITEM_LOV lov
where lov.item=im.item
and lov.uda_id=val.uda_id
and lov.UDA_VALUE=val.UDA_VALUE
and val.uda_id=3) as "SERIE",
(select val.uda_value_desc
from uda_values val, UDA_ITEM_date lov
where lov.item=im.item
and lov.uda_id=val.uda_id
and val.uda_id=20) as "UDA_DATE"
from ahl_rumm_prod_item_master im;
table ahl_rumm_prod_item_master has 313535 records.

One way that make minimal changes to your code is to change your correlated sub-queries to SELECT COUNT( ... ) FROM ... and then filter out the rows where something other than one result is returned:
SELECT *
FROM (
select im.item as "ITEM",
(select COUNT( val.uda_value_desc )
from uda_values val,
UDA_ITEM_LOV lov
where lov.item=im.item
and lov.uda_id=val.uda_id
and lov.UDA_VALUE=val.UDA_VALUE
and val.uda_id=3
) as "SERIE",
(select COUNT( val.uda_value_desc )
from uda_values val,
UDA_ITEM_date lov
where lov.item=im.item
and lov.uda_id=val.uda_id
and val.uda_id=20
) as "UDA_DATE"
from ahl_rumm_prod_item_master im
)
WHERE SERIE <> 1
OR UDA_DATE <> 1;
This will tell you the items where errors are occurring and you can investigate further.

One or both of your inner query return more than 1 row. therefore It cannot be set as a column value. What you should do is add some conditions to the inner queries to make sure that they return just one row

Related

Oracle: filter all rows before the ID

I have a big query that brings me a lot of rows, and based on each row I use this another query as a subselect.
This subselect brings me the following result rest on Oracle:
SELECT oc3.ID_ORGAO_INTELIGENCIA,
oc3.ord,
lag(oc3.ID_ORGAO_INTELIGENCIA, 1, NULL) OVER (
ORDER BY oc3.ord) ultimo
FROM
( SELECT DISTINCT oc2.*
FROM
( SELECT oc1.ID_ORGAO_INTELIGENCIA,
oc1.ID_ORGAO_INTELIGENCIA_PAI,
oc1.SG_ORGAO_INTELIGENCIA,
rownum AS ord
FROM TB_ORGAO_INTERNO oc1
WHERE oc1.DH_EXCLUSAO IS NULL START WITH oc1.ID_ORGAO_INTELIGENCIA =
-- this is a value that come from an outer select
-- If I put the value directly, like: S.ID_ORGAO_INTELIGENCIA, it does not work... I dont know why...
(SELECT sa.ID_ORGAO_INTELIGENCIA
FROM TB_SOLICITACAO sa
WHERE sa.ID_SOLICITACAO = 1077)-- s.ID_SOLICITACAO)
CONNECT BY
PRIOR oc1.ID_ORGAO_INTELIGENCIA_PAI = oc1.ID_ORGAO_INTELIGENCIA) oc2
INNER JOIN TB_PERMISSAO pe2_ ON pe2_.ID_ORGAO_INTELIGENCIA = oc2.ID_ORGAO_INTELIGENCIA
INNER JOIN TB_USUARIO u_ ON u_.ID_USUARIO = pe2_.ID_USUARIO
WHERE pe2_.ID_STATUS_PERMISSAO = 7
AND pe2_.ID_ATRIBUICAO IN :atribuicoes
ORDER BY oc2.ord) oc3
The result:
That important value from each row is the S.ID_SOLICITACAO, because based on that value that the subquery will be started.
I need to be able to filter the results by oc3.ID_ORGAO_INTELIGENCIA where it brings me all the rows before that number.
So, If I filter by 430, only the row with 311 will return.
If I filter by 329, it will bring me the: 311 and 430.
Is there a way to achieve this result?
One option might be to use your current query as a CTE, and then filter data it returns. Something like this:
with ycq as
-- your current query
(select ...
from ...
)
select *
from ycq a
where a.ord < (select b.ord
from ycq b
where b.id_orgao_inteligencia = :par_id_orgao_inteligencia
);

when with X as () compute? and about left join

hi i have 3 questions on sql please :
1-about this simple code
1. with cte as (
2. select * from TABLE1)
3. select * from cte
when select * from TABLE1 compute?
first the line 3 call and then line 1 then line 2
or first 1+2 and then 3?
2- when i do left/right join i have got some row with null, that make sense .
but how can i insert to the row will null "0" instead null?
to all of the row that because the left/right join get null ( if i use inner join i will not show this row )
thanks!
The order of execution is up to the database. The order of execution will depend on tables statistics and other factors. I've seen both order of execution.
If you have a NULL value and you want to show zero, use NVL for Oracle, e.g. NVL(myColumn,0) this will return myColumn if it's not null, otherwise 0. ISNULL for SQL Server and MySQL.

Count query giving wrong column name error

select COUNT(analysed) from Results where analysed="True"
I want to display count of rows in which analysed value is true.
However, my query gives the error: "The multi-part identifier "Results.runId" could not be bound.".
This is the actual query:
select ((SELECT COUNT(*) AS 'Count'
FROM Results
WHERE Analysed = 'True')/failCount) as PercentAnalysed
from Runs
where Runs.runId=Analysed.runId
My table schema is:
The value I want for a particular runId is: (the number of entries where analysed=true)/failCount
EDIT : How to merge these two queries?
i) select runId,Runs.prodId,prodDate,prodName,buildNumber,totalCount as TotalTestCases,(passCount*100)/(passCount+failCount) as PassPercent,
passCount,failCount,runOwner from Runs,Product where Runs.prodId=Product.prodId
ii) select (cast(counts.Count as decimal(10,4)) / cast(failCount as decimal(10,4))) as PercentAnalysed
from Runs
inner join
(
SELECT COUNT(*) AS 'Count', runId
FROM Results
WHERE Analysed = 'True'
GROUP BY runId
) counts
on counts.runId = Runs.runId
I tried this :
select runId,Runs.prodId,prodDate,prodName,buildNumber,totalCount as TotalTestCases,(passCount*100)/(passCount+failCount) as PassPercent,
passCount,failCount,runOwner,counts.runId,(cast(counts.Count as decimal(10,4)) / cast(failCount as decimal(10,4))) as PercentAnalysed
from Runs,Product
inner join
(
SELECT COUNT(*) AS 'Count', runId
FROM Results
WHERE Analysed = 'True'
GROUP BY runId
) counts
on counts.runId = Runs.runId
where Runs.prodId=Product.prodId
but it gives error.
Your problems are arising from improper joining of tables. You need information from both Runs and Results, but they aren't combined properly in your query. You have the right idea with a nested subquery, but it's in the wrong spot. You're also referencing the Analysed table in the outer where clause, but it hasn't been included in the from clause.
Try this instead:
select (cast(counts.Count as decimal(10,4)) / cast(failCount as decimal(10,4))) as PercentAnalysed
from Runs
inner join
(
SELECT COUNT(*) AS 'Count', runId
FROM Results
WHERE Analysed = 'True'
GROUP BY runId
) counts
on counts.runId = Runs.runId
I've set this up as an inner join to eliminate any runs which don't have analysed results; you can change it to a left join if you want those rows, but will need to add code to handle the null case. I've also added casts to the two numbers, because otherwise the query will perform integer division and truncate any fractional amounts.
I'd try the following query:
SELECT COUNT(*) AS 'Count'
FROM Results
WHERE Analysed = 'True'
This will count all of your rows where Analysed is 'True'. This should work if the datatype of your Analysed column is either BIT (Boolean) or STRING(VARCHAR, NVARCHAR).
Use CASE in Count
SELECT COUNT(CASE WHEN analysed='True' THEN analysed END) [COUNT]
FROM Results
Click here to view result
select COUNT(*) from Results where analysed="True"

Trouble performing a SQL insert using selects where more than 1 row is to be inserted

I'm not the strongest SQL developer (kinda new) but I thought I could do what I'm trying to do, but I'm receiving an error.
Basically, I'm trying to perform a mass insert based on some selects. The value of the first select in the statement below returns 1 groupid, but the 2nd statement returns a few hundred requestcategory id's. I am trying to perform these few hundred inserts with the statement below:
INSERT
INTO M_GROUPREQUESTCATEGORY
(
GROUPID,
REQUESTCATEGORYID
)
VALUES
(
(select groupid from esaws.m_group where name = 'Administration Group'),
(select requestcategoryid from esaws.m_grouprequestcategory where groupid = (select groupid from esaws.m_group where name = 'Customer Service Group'))
);
My issue is, SQL is returning the following error:
Error report -
SQL Error: ORA-01427: single-row subquery returns more than one row
01427. 00000 - "single-row subquery returns more than one row"
*Cause:
*Action:
Can someone please explain to me what I'm doing wrong, and what I need to change to get this working?
EDIT: To be clear, im trying to come up with a way to NOT have to write a few hundred indivdual inserts.
I suspect that this is what you want:
INSERT
INTO M_GROUPREQUESTCATEGORY
(
GROUPID,
REQUESTCATEGORYID
)
select DISTINCT G.groupid, R.requestcategoryid
from esaws.m_group G
Cross Join esaws.m_grouprequestcategory R
where G.name = 'Administration Group'
and R.groupid = (
select groupid
from esaws.m_group
where name = 'Customer Service Group')
and NOT EXISTS(Select * From esaws.m_grouprequestcategory R2
Where R2.GroupID = G.GroupID
And R2.requestcategoryid = R.requestcategoryid)
;
Which basically is Copying all of the request categories from the 'Customer Service Group' to the 'Administration Group', if I understand it correctly.
Subqueries in the select statement must evaluate to a single value, or else you will get this error. This makes sense since you are looking to fill the value for one field.
So when you say 'but the 2nd statement returns a few hundred requestcategory id's', then that's the error right there. You need to have it be only 1 for each result.
Simple way of doing Cross-Join
The way I understand your requirement is - You want to copy all groupIds from Admin Group to Customer Service Group - Based on that you want to have a Cross-Tab Join.
INSERT INTO schema.tgt_table_name
WITH groupid AS
(SELECT groupid
FROM esaws.m_group
WHERE NAME = 'Administration Group'),
requestcategoryid AS
(SELECT requestcategoryid
FROM esaws.m_grouprequestcategory
WHERE groupid = (SELECT groupid
FROM esaws.m_group
WHERE NAME = 'Customer Service Group'))
SELECT groupid.groupid, requestcategoryid.requestcategoryid
FROM groupid, requestcategoryid

Duplicate results returned from query when distinct is used

On a current project at I am needing to do some pagination of results returned from SQL. I have hit a corner case in which the query can accept identifiers as part of the where clause, normally this isn't an issue but in one case we have a single identifier being passed up that has a one to many relationship with one of the tables that the query joins on and it is returning multiple rows in the results. That issue was fixed by introducing a distinct to the query. The following is the query which returns the correct result of one row (all table/field names have been changed of course):
select distinct [item_table].[item_id]
, row_number() over (order by [item_table].[pub_date] desc, [item_table].[item_id]) as [row_num]
from [item_table]
join [OneToOneRelationShip] on [OneToOneRelationShip].[other_id] = [item_table].[other_id]
left join [OneToNoneOrManyRelationship] on [OneToNoneOrManyRelationship].[item_id] = [item_table].[item_id]
where [item_table].[pub_item_web] = 1
and [item_table].[live_item] = 1
and [item_table].[item_id] in (1404309)
However when I introduce pagination into the query I am finding that it is now returning multiple rows when it should be only be returning one. The method I am using for pagination is as follows:
select [item_id]
from (
select distinct [item_table].[item_id]
, row_number() over (order by [item_table].[pub_date] desc, [item_table].[item_id]) as [row_num]
from [item_table]
join [OneToOneRelationShip] on [OneToOneRelationShip].[other_id] = [item_table].[other_id]
left join [OneToNoneOrManyRelationship] on [OneToNoneOrManyRelationship].[item_id] = [item_table].[item_id]
where [item_table].[pub_item_web] = 1
and [item_table].[live_item] = 1
and [item_table].[item_id] in (1404309)
) as [items]
where [items].[row_num] between 0 and 100
I worry that adding a distinct to the outer query will cause an incorrect number of results to be returned and I am unsure of how else to fix this issue. The database I am querying is MS SQL Server 2008.
About 5 minutes after posting the question a possible solution hit me, if I group by the item_id (and any sort criteria) which should only be one instance of it should solve the issue. After testing this was the query that I was left with:
select [item_id]
from (
select [item_table].[item_id]
, row_number() over (order by [item_table].[pub_date] desc, [item_table].[item_id]) as [row_num]
from [item_table]
join [OneToOneRelationShip] on [OneToOneRelationShip].[other_id] = [item_table].[other_id]
left join [OneToNoneOrManyRelationship] on [OneToNoneOrManyRelationship].[item_id] = [item_table].[item_id]
where [item_table].[pub_item_web] = 1
and [item_table].[live_item] = 1
and [item_table].[item_id] in (1404309)
group by [item_table].[item_id], [item_table].[pub_date]
) as [items]
where [items].[row_num] between 0 and 100
I don't see where the DISTINCT is adding any value in your first query. The results are [item_table].[item_id] and [row_num]. Because the value of [row_num] is already distinct, the combination of [item_table].[item_id] and [row_num] will be distinct. When adding the DISTINCT keyword to the query, no rows are excluded.
In the second query, your results will return [item_id] from the sub query where [row_num] meets the criteria. If there where duplicate [item_id] values in the sub-query, there will be duplicates in the final results, but now you don't display [row_num] to distinguish the duplicates.