Getting ORA-01427 trying to select all from view I've created - oracle

I created a view from tables using these queries
CREATE VIEW AVAIL_TOOLS AS
SELECT T.TOOL_NAME AS "Name", R.RETAILER_NAME AS "Retailer", T.RETAILER_NUM AS "Number", I.TI_STATUS AS "Status",
(SELECT
CASE
WHEN DETAIL_RETURNDATE IS NULL THEN TO_CHAR(DETAIL_DUEDATE,'Day, Month, DD, YYYY')
ELSE 'Now' END FROM DETAILRENTAL) AS "Expected Avaliablity"
FROM TOOL T
INNER JOIN RETAILER R
ON T.RETAILER_NUM = R.RETAILER_NUM
INNER JOIN TOOLINSTANCE I
ON T.TOOL_NUM = I.TOOL_NUM
WHERE (I.TI_STATUS = 'Rented') OR (I.TI_STATUS = 'Available')
ORDER BY T.TOOL_NAME;
now when I try to run SELECT * FROM AVAIL_TOOLS
I receive the error ORA-01427: single-row subquery returns more than one row.
The case I am running in the query obviously seems to be the problem. Now is there anyway I could change the queries around. I am trying to create a view where if the return date is null it will be available when it is returned other wise it should be now.
I'm at a loss on how I should change about to get the resulted needed.

Query below should do what you want when you fill proper join condition.
CREATE VIEW AVAIL_TOOLS AS
SELECT T.TOOL_NAME AS "Name", R.RETAILER_NAME AS "Retailer", T.RETAILER_NUM AS "Number", I.TI_STATUS AS "Status",
CASE
WHEN DETAIL_RETURNDATE IS NULL THEN TO_CHAR(DETAIL_DUEDATE,'Day, Month, DD, YYYY')
ELSE 'Now' END "Expected Avaliablity"
FROM TOOL T
INNER JOIN RETAILER R
ON T.RETAILER_NUM = R.RETAILER_NUM
INNER JOIN TOOLINSTANCE I
ON T.TOOL_NUM = I.TOOL_NUM
LEFT OUTER JOIN DETAILRENTAL DR
ON (I.ID? = DR.TOOL_INSTANCE_ID?) --HERE fill join
WHERE (I.TI_STATUS = 'Rented') OR (I.TI_STATUS = 'Available')
ORDER BY T.TOOL_NAME;
Second option is adding to subquery with case where clause based on the same condition as join:
where I.INSTANCE_ID = DETAILRENTAL.INSTANCE_ID

You are combining the result of that CASE expression for ALL rows in DETAILRENTAL with ALL the rows from the three-table join. Instead, you probably only want the "expected availability" for the specific tool in the main SELECT. You could fix it by making the subquery into a correlated subquery; but it makes more sense to just have the CASE expression as a column in the outer SELECT, not wrapped within a subquery, and to add a join to DETAILRENTAL on whatever you need to join on (probably TOOL_NUM?)

Related

Trying to update a field in Oracle based on a select statement - getting subquery returns more than one row error

I am trying to update a field on a table the query needs to get the value from a 2nd table and use that to get the data from a 3rd table. I keep getting the "ORA-01427: single-row subquery returns more than one row" Any help is appreciated.
update ord_detail set cuser1 = (select c.email from contact c,ord_detail m join orders o on o.ID = m.orders_ID where c.email is not null)
where EXISTS (select email from contact,orders where orders.contact_id2 = contact.id)
Since you did not provide further information like the results of your sub selects, it's not 100% clear what exactly is your problem. You should check those results and if this does not answer your question, please provide the details.
My guess is that this sub query will give multiple rows because you are missing a join from the table "contact" to one of the other tables:
select c.email from contact c,ord_detail m
join orders o on o.ID = m.orders_ID where c.email is not null
Therefore, this sub query will always lead to many rows as result unless the table "contact" contains one row only whose column email is not null.

how to use select right after outer join keyword

The code SQL below is what I want to do but it's not working. Eventually I will convert that to LinQ query but for now, I just want to know how to make this works. I have one line matching in TemplateFields when I put where templateId =29 table and I want to full outer join with the TemplateAvailableFields. How can I use select right after full outer join?
select
ta.TemplateAvailableFieldId, ta.FieldName, ta.Required
from
TemplateAvailableFields as ta
full outer join
(select DefaultValue, DisplayOrder
from TemplateField
where TemplateId = 29) as t on ta.TemplateAvailableFieldId = t.TemplateAvailableFieldId;

SELECT Date with max date in Oracle

I have expression with db_link to MS SQL:
select b."Str" as "State" ,a."_Fld9059" as "Date" from
"_InfoRg9050"#SQLSERVER.UISLAB.COM a INNER JOIN
"EnumTexts"#SQLSERVER.UISLAB.COM b
on a."_Fld9052RRef" = b."_IDRRef"
where a."_Fld10998" = '1104000009' and
a."_Fld10998" = to_date(max(a."_Fld9059"),'dd.mm.yyyy')
order by a."_Fld9059" desc;
I want to upload value with maximum date. Can anybody help me ?
When I run this query I get ORA-00934 error.
The immediate cause of the error you are getting is that MAX() appears in the WHERE clause. One possible workaround, which might be what you intended, would be to use a subquery in the WHERE clause to identify the maximum date:
SELECT b.Str AS State,
a._Fld9059 AS Date
FROM _InfoRg9050 a
INNER JOIN EnumTexts b
ON a._Fld9052RRef = b._IDRRef
WHERE a._Fld10998 = '1104000009' AND
a._Fld10998 = (SELECT MAX(TO_DATE(_Fld9059, 'dd.mm.yyyy')) FROM _InfoRg9050)
ORDER BY a._Fld9059 DESC
However, it is not clear why you are comparing _InfoRg9050._Fld10998 to both the string '1104000009' and a date. You will need to resolve this on your own I believe to get a meaningful result.
Thank you for your help. I got it.
SELECT b."Str" AS "State"
FROM "_InfoRg9050"#SQLSERVER.UISLAB.COM a
INNER JOIN "EnumTexts"#SQLSERVER.UISLAB.COM b
ON a."_Fld9052RRef" = b."_IDRRef"
WHERE a."_Fld10998" = '1104000009' AND
a."_Fld9059" = (select MAX(a."_Fld9059") from "_InfoRg9050"#SQLSERVER.UISLAB.COM a
INNER JOIN "EnumTexts"#SQLSERVER.UISLAB.COM b
on a."_Fld9052RRef" = b."_IDRRef"
where a."_Fld10998" = '1104000009')
ORDER BY a."_Fld9059" DESC

PL SQL - Join 2 tables and return max from right table

Trying to retrive the MAX doc in the right table.
SELECT F43.PDDOCO,
F43.PDSFXO,
F43.PDLNID,
F43.PDAREC/100 As Received,
F431.PRAREC/100,
max(F431.PRDOC)
FROM PRODDTA.F43121 F431
LEFT OUTER JOIN PRODDTA.F4311 F43
ON
F43.PDKCOO=F431.PRKCOO
AND F43.PDDOCO=F431.PRDOCO
AND F43.PDDCTO=F431.PRDCTO
AND F43.PDSFXO=F431.PRSFXO
AND F43.PDLNID=F431.PRLNID
WHERE F431.PRDOCO = 401531
and F431.PRMATC = 2
and F43.PDLNTY = 'DC'
Group by
F43.PDDOCO,
F43.PDSFXO,
F43.PDLNID,
F43.PDAREC,
F431.PRAREC/100
This query is still returning the two rows in the right table. Fairly new to SQL and struggling with the statement. Any help would be appreciated.
Without seeing your data it is difficult to tell where the problem might so I will offer a few suggestions that could help.
First, you are joining with a LEFT JOIN on the PRODDTA.F4311 but you have in the WHERE clause a filter for that table. You should move the F43.PDLNTY = 'DC' to the JOIN condition. This is causing the query to act like an INNER JOIN.
Second, you can try using a subquery to get the MAX(PRDOC) value. Then you can limit the columns that you are grouping on which could eliminate the duplicates. The query would them be similar to the following:
SELECT F43.PDDOCO,
F43.PDSFXO,
F43.PDLNID,
F43.PDAREC/100 As Received,
F431.PRAREC/100,
F431.PRDOC
FROM PRODDTA.F43121 F431
INNER JOIN
(
-- subquery to get the max
-- then group by the distinct columns
SELECT PDKCOO, max(PRDOC) MaxPRDOC
FROM PRODDTA.F43121
WHERE PRDOCO = 401531
and PRMATC = 2
GROUP BY PDKCOO
) f2
-- join the subquery result back to the PRODDTA.F43121 table
on F431.PRDOC = f2.MaxPRDOC
AND F431.PDKCOO = f2.PDKCOO
LEFT OUTER JOIN PRODDTA.F4311 F43
ON F43.PDKCOO=F431.PRKCOO
AND F43.PDDOCO=F431.PRDOCO
AND F43.PDDCTO=F431.PRDCTO
AND F43.PDSFXO=F431.PRSFXO
AND F43.PDLNID=F431.PRLNID
AND F43.PDLNTY = 'DC' -- move this filter to the join instead of the WHERE
WHERE F431.PRDOCO = 401531
and F431.PRMATC = 2
If you provide your table structures and some sample data, it will be easier to determine the issue.

Linq To Entity Framework selecting whole tables

I have the following Linq statement:
(from order in Orders.AsEnumerable()
join component in Components.AsEnumerable()
on order.ORDER_ID equals component.ORDER_ID
join detail in Detailss.AsEnumerable()
on component.RESULT_ID equals detail.RESULT_ID
where orderRestrict.ORDER_MNEMONIC == "MyOrderText"
select new
{
Mnemonic = detail.TEST_MNEMONIC,
OrderID = component.ORDER_ID,
SeqNumber = component.SEQ_NUM
}).ToList()
I expect this to put out the following query:
select *
from Orders ord (NoLock)
join Component comp (NoLock)
on ord .ORDER_ID = comp.ORDER_ID
join Details detail (NoLock)
on comp.RESULT_TEST_NUM = detail .RESULT_TEST_NUM
where res.ORDER_MNEMONIC = 'MyOrderText'
but instead I get 3 seperate queries that select all rows from the tables. I am guessing that Linq is then filtering the values because I do get the correct values in the end.
The problem is that it takes WAY WAY too long because it is pulling down all the rows from all three tables.
Any ideas how I can fix that?
Remove the .AsEnumerable()s from the query as these are preventing the entire query being evaluated on the server.

Resources