I have scenario below. I have a table Orders(OrderId, ItemId) and i want to get all the orders where ItemId 1 and 2 is coming simulataneoudsly
OrderId ItemId
1000 1
1001 2
1002 1
1002 2
1002 3
1003 1
1003 2
1004 4
1004 5
1005 3
1006 1
1006 3
as per above table's data and the ask ....i should get output OrderId 1002 and 1003.
Use COUNT and HAVING:
SELECT OrderId
FROM Orders
WHERE
ItemId IN(1, 2)
GROUP BY OrderId
HAVING COUNT(ItemId) = 2
If duplicate ItemId is allowed in an OrderId, use:
HAVING COUNT(DISTINCT ItemId) = 2
ONLINE DEMO
Another option, using nested queries, would be:
SELECT orderId
FROM ORDERS o
WHERE o.itemId = 1
AND EXISTS (SELECT 'X'
FROM ORDERS o1
WHERE o1.orderId = o.orderId
AND o1.itemId = 2);
ONLINE DEMO
Related
I have the following tables:
invoice
id
customerId
date
1
3
2020-10-10
2
NULL
2020-09-10
3
1
2020-10-15
product
id
name
price
1
car
10
2
pen
5
3
laptop
6
4
table
2
customer
id
name
1
a
2
b
3
c
4
d
invoceProduct
id
invoiceid
productid
1
1
1
3
1
2
4
1
4
5
2
2
6
2
3
I need to get the following for each invoice:
invoiceID, date, customerName, Total, Quantity(count of items), max product name and price, min product name and price in each invoice.
I wrote query and get most of values but I cannot get the name of products.
This is my sql query
WITH cte_Products(InvoiceId, date, CustomerName, ProductName, price) AS
(
select
i.id as InvoiceId,
i.date as date,
CASE
when c.name IS NULL THEN 'NoName'
Else c.name
End AS CustomerName,
p.name as ProductName,
p.price as price
from invoceProduct ip
join product p on p.id = ip.productID
join invoice i on i.id = ip.invoiceId
left join customer c on i.customerId = c.id
)
select
cte.InvoiceId,
cte.date,
cte.CustomerName,
SUM(cte.price) as Total,
count(*) AS ItemsQuantity,
MAX(cte.price) AS MostExpensiveItem,
MIN(cte.price) AS CheapestItem
from
cte_Products cte
group by cte.InvoiceId, cte.date, cte.CustomerName;
I got this result
InvoiceId
date
CustomerName
Total
ItemsQuantity
MostExpensiveItem
CheapestItem
1
2020-10-10
c
17
3
10
2
2
2020-09-10
NoName
11
2
6
5
I need to add the product name with product price under MostExpensiveItem and CheapestItem.
I would like an SQL query that returns 'Orders' based on the associated 'Product', the 'Product.DepositId' has to equal an exact integer value (for example Product.DepositId = 1).
If the associated 'Product.DepositId' is null, then the query needs to go up the Product ladder get the parent 'Product' using 'Product.ParentId' and so on.
A 'Product' parent hierarchy can go 'N' tiers/layers. (for example Child -> ChildParent -> ChildParent -> Final Parent)
Multiple 'Product' children can be associated to the same Parent
Only the top most parent 'Product' will have a DepositId. So if the 'Product.ParentId' is null then the 'Product.DepositId' will not be null
An 'Order' can be associated with a child 'Product' or with a parent 'Product'. (Parents can have orders as well.)
For example (to make the example simple I used integer ids instead of uniqueidentifier)
Products
Id ParentId DepositId
1 NULL 10
2 NULL 20
3 1 NULL
4 2 NULL
5 1 NULL
6 3 NULL
Orders
Id ProductId
1001 1
1002 2
1003 3
1004 4
1005 5
1006 6
Expected Result Orders with DepositId = 10
OrderId ProductId
1001 1 --Because Product 1 DepositId = 10
1003 3 --Because Product 3 is child of Product 1
1005 5 --Because Product 5 is child of Product 1
1006 6 --Because Product 6 is child of Product 3 which in
turn is a child of Product 1
This calls for a recursive CTE.
;with rcte_products as (
select Id as ProductId, ParentId
, DepositId
, 0 as Lvl
, Id as BaseId
from Products
where DepositId = 10
union all
select t.Id, t.ParentId
, c.DepositId
, c.Lvl+1
, c.BaseId
from rcte_products c
join Products t on t.ParentId = c.ProductId
)
select
o.Id as OrderId
, o.ProductId
from rcte_products c
join Orders o
on o.ProductId = c.ProductId
order by o.Id;
OrderId
ProductId
1001
1
1003
3
1005
5
1006
6
Demo on db<>fiddle here
I just want to get the result which displays the reference which is not tallied in sum of table2. when i run my query below it will give me an wrong sum which it gets doubled even if group by cusid ,refno.
Table 1
RefNo
CusID
TotalAmount
1
1001
50
2
1001
30
3
1002
40
Table 2
RefNo
CusID
Particular
Amount
1
1001
Paper
30
1
1001
Pencil
30
2
1001
Ball
15
2
1001
Rubber
20
3
1002
Laptop
50
select * from Table1 a
INNER JOIN (Select CusID,RefNo, SUM(Amount) as CorrectTotal from Table2 group by
CusID,RefNo,
)b
ON b.CusID= a.CusID AND b.RefNo= a.RefNo
where a.TotalAmount != CorrectTotal
Expected Result
If you do it with FULL JOIN and with GROUP BY, you will also get rows where there is no record in the other table.
SELECT COALESCE(a.RefNo, b.RefNo) AS RefNo
, COALESCE(a.CusID, b.CusID) AS CusID
, a.TotalAmount
, SUM(b.Amount) AS CorrectTotal
FROM table1 a
FULL JOIN table2 b ON a.RefNo = b.RefNo
AND a.CusID = b.CusID
GROUP BY COALESCE(a.RefNo, b.RefNo)
, COALESCE(a.CusID, b.CusID)
, a.TotalAmount
ORDER BY 1, 2
Output
RefNo
CusID
TotalAmount
CorrectTotal
1
1001
50
60
2
1001
30
35
3
1002
40
50
8
888
88
(null)
9
999
(null)
99
See running demo on SQL Fiddle.
The other answer will work, but if you don't want to mess with a GROUP BY on the whole query you can also use an APPLY to do this:
SELECT a.*, c.CorrectAmount
FROM Table1 a
OUTER APPLY (
SELECT SUM(Amount) AS CorrectAmount
FROM Table2 b
WHERE b.CusID = a.CusID AND b.RefNo = a.RefNo
) c
WHERE a.TotalAmount <> c.CorrectAmount
So I have a situation which can be referred to the table below:
TABLE A TABLE B TABLE C
ID TOTAL_PRICE ORDER_ID ID ID ORDER ID
1 10 101 101 1001 101
2 20 101 103 1002 101
3 25 103 1003 103
4 10 103 1004 103
With all these tables I'm expecting of this result:
EXPECTED OUTPUT
ID TOTAL_PRICE ORDER_ID ID
1 10 101 1001
2 20 101 1002
3 25 103 1003
4 10 103 1004
And the result that I get follows:
REAL OUTPUT
ID TOTAL_PRICE ORDER_ID ID
1 10 101 1001
1 10 101 1002
2 20 101 1001
2 20 101 1002
3 25 103 1003
3 25 103 1004
4 10 103 1003
4 10 103 1004
My sql as follows and I'm using SQL Oracle:
SELECT a.id, a.total_price, a.order.id, c.id
FROM a,b,c
WHERE a.order_id=b.id AND b.id=c.order_id
With that situation, how can I solve the problem in order to get the expected output? Thank you.
It seems that you want to assign one id from table c for each row from table a given your matching tables criteria. For this you could use row_number to enumerate your rows inside tables a and c and then assign this information with the row number respectively:
select
a.id, a.total_price, a.order_id, c.id
from (select *, row_number over (partition by order_id order by id) as rn from a) a
join b on a.order_id = b.id
join (select id, order_id, row_number over (partition by order_id order by id) as rn from c) on b.id = c.order_id
where a.rn = c.rn
This is my orders table. I want to report all orders which all details are Ready For Shipment.
orderNo detailNo statusId status
10001 1 40 Ready For Shipment
10002 1 40 Ready For Shipment
10002 2 20 Canceled
10002 3 30 Pending
10003 1 40 Ready For Shipment
10003 2 40 Ready For Shipment
10004 1 10 New Order
10004 2 20 Canceled
10004 3 40 Ready For Shipment
10004 4 40 Ready For Shipment
Expected results are:
Orders Ready For Shipment
10001
10003
Are there any effective method to achieve ready orders list without using subqueries?
Group by the orderno and use a havingto get only those groups having no other status
select orderno
from your_table
group by orderno
having sum(case when status <> 'Ready For Shipment' then 1 end) = 0
or with the statusId
select orderno
from your_table
group by orderno
having sum(case when statusid <> 40 then 1 end) = 0
select Distinct a.orderId
from ordersTable a
inner join
(
select orderNo, Avg(statusId)
from ordersTable
group by orderNo
having Avg(statusId) = 40) b
on a.orderNo = b.orderNo
Have you tried this?
SELECT orderNo from <TABLE NAME>
WHERE status="Ready For Shipment" ORDER BY orderNo