List orders which all rows are ready - sql

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

Related

SQL get SUM, COUNT, max, min and names of invoice

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.

SQL return rows based on column value condition

I have below tables
Order Table
OrderNo CategoryID SubCategoryID CountryID
100 7 1 3
200 8 2 5
300 7 2 4
400 2 6 2
Tracking Table
OrderNo CountryID TrackingTypeID
100 2 1
200 1 2
100 3 3
400 5 5
200 2 2
Reviewed Table
OrderNo
300
100
200
Expected Result
OrderNo SubCategoryID CategoryID CountryID CountryID
100 1 7 3 3
200 2 8 5 5
300 2 7 4 4
Each subCategory belongs to one Category.
Now I want to write a query for below requirements.
Returns only orders of CategoryID (7,8)
1.1 In case the order has SubCategoryID (1,4)
return only orders which has a record in Tracking table with
same CountryID as in Order table.
And that order should not have a TrackingTypeID of (5,6) in Tracking
table.
1.2 In case the order has SubCategoryID (2,6) then that order must
have a record in Reviewed table and that order should not have a
TrackingTypeID (5,6) in Tracking table
Exclude all orders which have SubCategoryID that not belong to CategoryID (7,8)
I wrote below script but the issue is that it's always run the second condition only.And no order which satisfies the first condition is being returned.
But if I run the script with the first condition only I get these orders. I don't know what I'm doing wrong here.
SELECT DISTINCT o.orderNo , o.subCategoryId , o.categoryId ,
o.countryId , Tracking.countryId
FROM [Order] o
JOIN Tracking ON o.orderNo = Tracking.orderNo
WHERE
(o.subCategoryId IN (1,4 ) AND o.countryId = Tracking.countryId AND
EXISTS (SELECT 1
FROM tracking t
WHERE t.orderNo = o.orderNo AND t.countryId = o.countryId)
AND NOT EXISTS ( SELECT 1
FROM tracking t
WHERE t.orderNo = o.orderNo
AND TrackingTypeID IN (5,6))
)
OR
(o.subCategoryId in (
SELECT id FROM subCatgory WHERE categoryId in (7,8)
AND ID NOT IN (1 , 4)
)
AND EXISTS (SELECT 1
FROM Reviewed r
WHERE r.orderNo = r.orderNo
)
AND NOT EXISTS ( SELECT 1
FROM tracking t
WHERE t.orderNo = o.orderNo
AND TrackingTypeID IN (5,6))
)

Get all the orders for ItemId 1 and 2 simultaneously

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

Last Record Of Each Group Using Multiple Joins In Sql Server

I Have 3 tables Customer, Bank and BankTransaction.
On My View I want to display each customer with their Balance in the bank account.
Here is my tables
Customer
Id Name
---------
1 John
2 Jack
Bank
Id CustomerId BankName
----------------------------------
1 1 HSBC
2 2 HSBC
BankTransaction
Id BankID MoneyIn MoneyOut Balance
---------------------------------------------
1 1 1000 0 1000
2 1 0 500 500
3 2 2000 0 2000
4 2 2000 0 4000
5 2 1000 0 5000
Now I want to Display following data view query
John 500
Jack 5000
Last Balance of each customer
Try this
SELECT A.Name,
Sum(C.MoneyIN) - Sum(C.MoneyOut) AS Balance
FROM #Customer A
JOIN #Bank B ON A.Id = B.id
JOIN #BankTransaction C ON B.Id = C.BankID
GROUP BY A.Name
Using Window function you can get the result. Try this.
;WITH cte
AS (SELECT Row_number() OVER (partition BY b.id ORDER BY a.id DESC) rn,
c.Name,
a.balance
FROM BankTransaction a
JOIN bank b ON a.BankID = b.Id
JOIN Customer c ON c.Id = b.CustomerId)
SELECT name, balance
FROM cte
WHERE rn = 1

Case Overriding where?

Ok so i have one table with lets call it A(there are more items here):
ITEMID NAME
10001 Boat
I have another table lets call it B(there are more items here):
Itemid Price Pricetype Dimension Valid_from Valid_To
10001 10 1 Allblank 2014-10-10 2014-10-25
10001 5 2 200 2014-10-09 2014-10-20
10001 99 2 200 2014-10-08 2014-10-10
10001 20 1 Allblank 2014-10-08 2014-10-10
10001 22 2 500 2014-10-10 2014-10-19
Price type determines wherever item is on sale or no so i want to list the regular price at its dimension and the sales price at the dimension so the table should look like this (assuming that 1 is regular price and 2 is sale price):
Itemid Itemname RegularPrice DiscountPrice200 DiscountPrice500
10001 boat 10 5 22
I've inner joined tables, but i cant manage to manage the fields right , case statement returns a lot of duplicates on inner join. I hope i made myself clear :)
My query:
SELECT a.itemid,
case when b.inventdimid = '00000101_090' and (b.labelissue ='1' or b.labelissue = '2' and (b.todate > getdate() or b.todate ='1900-01-01 00:00:00.000') ) then b.amount else null end as Price500
FROM a
inner join b
on a.itemid = b.itemrelation
Try this query:
SELECT b.itemid,
a.name,
b.price,
b200.price,
b500.price
FROM tb b
JOIN ta a
ON b.itemid = a.itemid
JOIN tb b200
ON b.itemid = b200.itemid
AND b200.valid_to > getdate()
AND b200.pricetype = 2
AND b200.dimension = 200
JOIN tb b500
ON b.itemid = b500.itemid
AND b500.valid_to > getdate()
AND b500.pricetype = 2
AND b500.dimension = 500
WHERE b.valid_to > getdate()
AND b.pricetype = 1