techlearn
asked on
Oracle SQL Query help
Experts,
Need some help with query.
Order table:
OrderNo, ItemNo, ItemStatus
1234 , 56566, Sent
1234, 44545, Hold
1234, 67888, Processing
4567 , 65656, Sent
4567 , 45466, Hold
4566, 34566, Hold
Transaction Table:
Order No, Item No, Sub Item no, SubitemStatus
1234 , 56566, 5656601, Sent
1234 , 56566, 5656602, Sent
1234 , 44545, 4454501, Sent
1234 , 44545, 4454502, Sent
1234, 67888, 6788801, Sent
4567 , 65656, 6565601 Hold
4567 , 45466, 4546601 Sent
4567 , 45466, 4546602 Processing
4566, 34566, 3456601 Sent
4566, 34566, 3456602 Sent
Basically, i want to return only the records for the SubitemsStatus= "Sent" each record for the Order should be Sent status, if one record is 'sent' and other is 'Processing' 'hold' etc. than exclude the entire order no. For the above table. My result set should return..
Order No, 1234 and 4566. Order 4567 should not be returned as one of the record Status is 'Hold' and 'processing'.
Thanks in advance.
Need some help with query.
Order table:
OrderNo, ItemNo, ItemStatus
1234 , 56566, Sent
1234, 44545, Hold
1234, 67888, Processing
4567 , 65656, Sent
4567 , 45466, Hold
4566, 34566, Hold
Transaction Table:
Order No, Item No, Sub Item no, SubitemStatus
1234 , 56566, 5656601, Sent
1234 , 56566, 5656602, Sent
1234 , 44545, 4454501, Sent
1234 , 44545, 4454502, Sent
1234, 67888, 6788801, Sent
4567 , 65656, 6565601 Hold
4567 , 45466, 4546601 Sent
4567 , 45466, 4546602 Processing
4566, 34566, 3456601 Sent
4566, 34566, 3456602 Sent
Basically, i want to return only the records for the SubitemsStatus= "Sent" each record for the Order should be Sent status, if one record is 'sent' and other is 'Processing' 'hold' etc. than exclude the entire order no. For the above table. My result set should return..
Order No, 1234 and 4566. Order 4567 should not be returned as one of the record Status is 'Hold' and 'processing'.
Thanks in advance.
Or in traditional Oracle SQL syntax:
select * from orders o
where (o.order_no, o.itemno) in (select t.order_no,t. item_no, max(t.subitemstatus)
from transaction_table t
where t.subitemstatus = 'Sent'
group by t.order_no,t. item_no);
If your Oracle database version is 11 or higher, you can use either ANSI-standard or traditional Oracle join syntax. I would suggest trying them both to see if one approach or the other works faster in your system.
select * from orders o
where (o.order_no, o.itemno) in (select t.order_no,t. item_no, max(t.subitemstatus)
from transaction_table t
where t.subitemstatus = 'Sent'
group by t.order_no,t. item_no);
If your Oracle database version is 11 or higher, you can use either ANSI-standard or traditional Oracle join syntax. I would suggest trying them both to see if one approach or the other works faster in your system.
ASKER
Thanks Paul. Query in not working as it should be. It's showing sent as well as hold records. Can you please check once?
Markgeer: I tried you query too. Throwing this error.
ORA 00913 Too many values.
Markgeer: I tried you query too. Throwing this error.
ORA 00913 Too many values.
ASKER
Please help. What should be done?
This is what my previous query returns the following:
And that result meets this requirement:
"Order 4567 should not be returned as one of the record Status is 'Hold' and 'processing'. "
but:
>>" Query in not working as it should be. "
The trouble is you haven't really shown us what the correct result should be.
Please, using only the sample data you already provided, exactly what output are you expecting from the query?
| ORDERNO | ITEMNO | ITEMSTATUS | ORDERNO |
|---------|--------|------------|---------|
| 1234 | 56566 | Sent | 1234 |
| 1234 | 44545 | Hold | 1234 |
| 1234 | 67888 | Processing | 1234 |
| 4566 | 34566 | Hold | 4566 |
And that result meets this requirement:
"Order 4567 should not be returned as one of the record Status is 'Hold' and 'processing'. "
but:
>>" Query in not working as it should be. "
The trouble is you haven't really shown us what the correct result should be.
Please, using only the sample data you already provided, exactly what output are you expecting from the query?
ASKER
Hi Maxwell,
Sorry, I apologize. The above result set is good. I missed some important info. In Transaction table we can have records with other status as well. Please see below.
Transaction Table:
Order No, Item No, Sub Item no, SubitemStatus
1234 , 56566, 5656601, Sent
1234 , 56566, 5656602, Sent
1234 , 44545, 4454501, Sent
1234 , 44545, 4454502, Sent
A1234, 67888, 6788801, Hold
4567 , 65656, 6565601 Hold
4567 , 45466, 4546601 Sent
4567 , 45466, 4546602 Processing
4566, 34566, 3456601 Sent
A4566, 34566, 3456602 Processing
In the above table I have added A as a prefix in Order no 1234 and Order no 4566.
The result set still should be the same...
| ORDERNO | ITEMNO | ITEMSTATUS | ORDERNO |
|---------|--------|------ ------|--- ------|
| 1234 | 56566 | Sent | 1234 |
| 1234 | 44545 | Hold | 1234 |
| 1234 | 67888 | Processing | 1234 |
| 4566 | 34566 | Hold | 4566 |
Sorry, I apologize. The above result set is good. I missed some important info. In Transaction table we can have records with other status as well. Please see below.
Transaction Table:
Order No, Item No, Sub Item no, SubitemStatus
1234 , 56566, 5656601, Sent
1234 , 56566, 5656602, Sent
1234 , 44545, 4454501, Sent
1234 , 44545, 4454502, Sent
A1234, 67888, 6788801, Hold
4567 , 65656, 6565601 Hold
4567 , 45466, 4546601 Sent
4567 , 45466, 4546602 Processing
4566, 34566, 3456601 Sent
A4566, 34566, 3456602 Processing
In the above table I have added A as a prefix in Order no 1234 and Order no 4566.
The result set still should be the same...
| ORDERNO | ITEMNO | ITEMSTATUS | ORDERNO |
|---------|--------|------
| 1234 | 56566 | Sent | 1234 |
| 1234 | 44545 | Hold | 1234 |
| 1234 | 67888 | Processing | 1234 |
| 4566 | 34566 | Hold | 4566 |
I do not currently see how that added data make any difference to outcome.
1234 transactions are all = 'sent', so order 1234 is included
4566 transactions are all ='sent', so order 4566 is included
orders A1234, A4566 and 4567 do not have all transactions as 'sent', so they are excluded.
------------ BUT
Are you also trying to indicate that order 'A1234' should in some way be linked to order '1234'?
and that order 'A4566' is related to '4566'?
If this is true then NONE of the orders have ALL transactions = 'sent' and therefore NONE would be returned.
So. bottom line, I am confused by the new information.
1234 transactions are all = 'sent', so order 1234 is included
4566 transactions are all ='sent', so order 4566 is included
orders A1234, A4566 and 4567 do not have all transactions as 'sent', so they are excluded.
------------ BUT
Are you also trying to indicate that order 'A1234' should in some way be linked to order '1234'?
and that order 'A4566' is related to '4566'?
If this is true then NONE of the orders have ALL transactions = 'sent' and therefore NONE would be returned.
So. bottom line, I am confused by the new information.
ASKER
Sorry, Max. Made a mistake again.. I apologize. Please see the change now. I expect the same result set as before. In transaction table Item No. can be null and Sub Item no can start with prefix A. This kind of record should be excluded. Again, i am sorry for the earlier confusion.
Transaction Table:
Order No, Item No, Sub Item no, SubitemStatus
1234 , 56566, 5656601, Sent
1234 , 56566, 5656602, Sent
1234 , 44545, 4454501, Sent
1234 , 44545, 4454502, Sent
1234, Null, A6788801, Hold
1234, Null, A4566866, Hold
4567 , 65656, 6565601 Hold
4567 , 45466, 4546601 Sent
4567 , 45466, 4546602 Processing
4566, 34566, 3456601 Sent
4566, Null, A3456602 Processing
==================
| ORDERNO | ITEMNO | ITEMSTATUS | ORDERNO |
|---------|--------|------ ------|--- ------|
| 1234 | 56566 | Sent | 1234 |
| 1234 | 44545 | Hold | 1234 |
| 1234 | 67888 | Processing | 1234 |
| 4566 | 34566 | Hold | 4566 |
Transaction Table:
Order No, Item No, Sub Item no, SubitemStatus
1234 , 56566, 5656601, Sent
1234 , 56566, 5656602, Sent
1234 , 44545, 4454501, Sent
1234 , 44545, 4454502, Sent
1234, Null, A6788801, Hold
1234, Null, A4566866, Hold
4567 , 65656, 6565601 Hold
4567 , 45466, 4546601 Sent
4567 , 45466, 4546602 Processing
4566, 34566, 3456601 Sent
4566, Null, A3456602 Processing
==================
| ORDERNO | ITEMNO | ITEMSTATUS | ORDERNO |
|---------|--------|------
| 1234 | 56566 | Sent | 1234 |
| 1234 | 44545 | Hold | 1234 |
| 1234 | 67888 | Processing | 1234 |
| 4566 | 34566 | Hold | 4566 |
then exclude them using a where clause ....
WHERE Item_No IS NOT NULL appears to cover both conditions, if not add
AND NOT Item_No LIKE 'A%'
but don't add it if is not needed
SELECT
*
FROM orders
INNER JOIN (
SELECT
Order_No
FROM transactions
WHERE Item_No IS NOT NULL
GROUP BY
Order_No
HAVING MIN(SubitemStatus) = MAX(SubitemStatus)
AND MAX(SubitemStatus) = 'Sent'
) all_sent ON orders.Order_No = all_sent.Order_No
;
WHERE Item_No IS NOT NULL appears to cover both conditions, if not add
AND NOT Item_No LIKE 'A%'
but don't add it if is not needed
Or, to fix up my earlier suggestion add one word, like this:
select * from orders o
where (o.order_no, o.itemno, 'Sent') in (select t.order_no,t. item_no, max(t.subitemstatus)
from transaction_table t
where t.subitemstatus = 'Sent'
group by t.order_no,t. item_no);
select * from orders o
where (o.order_no, o.itemno, 'Sent') in (select t.order_no,t. item_no, max(t.subitemstatus)
from transaction_table t
where t.subitemstatus = 'Sent'
group by t.order_no,t. item_no);
ASKER
Max,
Thanks it works, but the only problem i am seeing is. Its pulling all the records from Orders table where ItemStatus is Sent, Processing, Hold. I don't want to see the orders for which all the ItemNo Status is Sent and all Transactions Status for respective order no are Sent. See the Sample below. 4355 should not be displayed.
Order table:
OrderNo, ItemNo, ItemStatus
4355 , 35643, Sent
4355 , 35643, Sent
4355 , 35643, Sent
Transaction Table:
Order No, Item No, Sub Item no, SubitemStatus
4355 , 35643, 9956601, Sent
4355 , 35643, 9956602, Sent
4355 , 35643, 9954501, Sent
Thanks it works, but the only problem i am seeing is. Its pulling all the records from Orders table where ItemStatus is Sent, Processing, Hold. I don't want to see the orders for which all the ItemNo Status is Sent and all Transactions Status for respective order no are Sent. See the Sample below. 4355 should not be displayed.
Order table:
OrderNo, ItemNo, ItemStatus
4355 , 35643, Sent
4355 , 35643, Sent
4355 , 35643, Sent
Transaction Table:
Order No, Item No, Sub Item no, SubitemStatus
4355 , 35643, 9956601, Sent
4355 , 35643, 9956602, Sent
4355 , 35643, 9954501, Sent
SELECT
ORDERNO, ITEMNO, ITEMSTATUS
FROM (
SELECT
o.ORDERNO, o.ITEMNO, o.ITEMSTATUS
, MIN(o.ITEMSTATUS) OVER(PARTITION BY o.ORDERNO) AS MINSTATUS
, MAX(o.ITEMSTATUS) OVER(PARTITION BY o.ORDERNO) AS MAXSTATUS
FROM orders o
INNER JOIN (
SELECT
OrderNo
FROM transactions
GROUP BY
OrderNo
HAVING MIN(SubitemStatus) = MAX(SubitemStatus)
AND MAX(SubitemStatus) = 'Sent'
) all_sent ON o.OrderNo = all_sent.OrderNo
) ALL_O
WHERE NOT (MINSTATUS = 'Sent' AND MAXSTATUS = 'Sent')
;
are all the requirements known now?
ASKER
Hi Max, Thanks.
When i run the above query, I do not get the below results.
Is it accounting for all the rules i have given above. Like one of them was (WHERE Item_No IS NOT NULL) in Transactions table.
| ORDERNO | ITEMNO | ITEMSTATUS | ORDERNO |
|---------|--------|------ ------|--- ------|
| 1234 | 56566 | Sent | 1234 |
| 1234 | 44545 | Hold | 1234 |
| 1234 | 67888 | Processing | 1234 |
| 4566 | 34566 | Hold | 4566 |
When i run the above query, I do not get the below results.
Is it accounting for all the rules i have given above. Like one of them was (WHERE Item_No IS NOT NULL) in Transactions table.
| ORDERNO | ITEMNO | ITEMSTATUS | ORDERNO |
|---------|--------|------
| 1234 | 56566 | Sent | 1234 |
| 1234 | 44545 | Hold | 1234 |
| 1234 | 67888 | Processing | 1234 |
| 4566 | 34566 | Hold | 4566 |
I'm sorry is that result showing above NOT what you get? if so, what DO you get instead?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Sorry, for the delayed response.. I was not able to login to the forum lately. Thanks for your help.
Open in new window
Using a GROUP BY and HAVING clause will allow you to find only those where all are sent.
You haven't specified what the "expected result" should look like so I have just assumed you want rows from the orders table.
details:
Open in new window