How to apply WHERE clause to multiple SELECT statements in SQL Server - sql

I am creating an query that selects data from multiple tables. I have completed all the query but now I have to apply the WHERE clause to the whole query.
I have 9 select statements, and these are working fine. Data is being selected from different tables. Now I want to declare date session and I want all data to be filtered according to the date provided. I am using the below query:
SELECT
(SELECT COUNT(DISTINCT OrderItems.ProductID)
FROM OrderItems) AS 'TotalSoldItemsDistinct',
(SELECT COUNT(OrderItems.ProductID)
FROM OrderItems) AS 'TotalSoldItemsInDistinct',
(SELECT COUNT(Orders.OrderID)
FROM Orders) AS 'TotalOrders',
(SELECT COUNT(Orders.OrderID)
FROM Orders
WHERE Orders.OrderStatusID = #CompleteOStatusID) AS 'CompleteOrders',
(SELECT COUNT(Orders.OrderID)
FROM Orders
WHERE Orders.OrderStatusID = #PendingOStatusID) AS 'PendingOrders',
(SELECT COUNT(Orders.ClientID)
FROM Orders
WHERE Orders.ClientID != #WalkingCustID) AS 'namedcustomers',
(SELECT COUNT(Orders.ClientID)
FROM Orders
WHERE Orders.ClientID = #WalkingCustID) AS 'WalkingCustomers',
(SELECT SUM(OrderItems.PurchasePrice)
FROM OrderItems) AS 'TotalPurchasePrice',
(SELECT SUM(OrderItems.SalePrice)
FROM OrderItems) AS 'TotalSalePrice'
I am selecting data from 2 tables named 'Orders' and 'OrderItems', I have column TransactionDate in 'Orders' table and column OrderDate in OrderItems table on that I want to use where filter. Can anybody please suggest how to apply filter to whole query?

You could try this
;with tempOrderItems AS
(
SELECT
COUNT(DISTINCT OrderItems.ProductID) AS 'TotalSoldItemsDistinct',
COUNT(OrderItems.ProductID) AS 'TotalSoldItemsInDistinct',
SUM(OrderItems.PurchasePrice) AS 'TotalPurchasePrice',
SUM(OrderItems.SalePrice) AS 'TotalSalePrice'
FROM OrderItems ori
WHERE OrderDate BETWEEN xxx AND yyy
)
, tempOrders AS
(
SELECT
COUNT(o.OrderID) AS 'TotalOrders',
SUM(CASE WHEN o.OrderStatusID = #CompleteOStatusID THEN 1 ELSE 0 END) AS 'CompleteOrders',
SUM(CASE WHEN o.OrderStatusID = #PendingOStatusID THEN 1 ELSE 0 END) AS 'PendingOrders',
SUM(CASE WHEN o.ClientID != #WalkingCustID THEN 1 ELSE 0 END) AS 'namedcustomers',
SUM(CASE WHEN o.ClientID = #WalkingCustID THEN 1 ELSE 0 END) AS 'WalkingCustomers'
FROM Orders o
WHERE TransactionDate BETWEEN xxx AND yyy
)
SELECT * FROM tempOrderItems
CROSS JOIN tempOrders

It is not fully clear what you want as a result, but here 2 approaches.
Try the following for selecting data from 2 tables at the same time (replace the date with your criteria):
SELECT * FROM Orders AS o INNER JOIN OrderItems AS i WHERE o.TransactionDate = '2015-02-12' AND i.OrderDate = '2015-02-12';
The SELECT * selects all columns from both tables as a result and the WHERE ... AND ...-clause filters for results only with your defined date.
Try the following for selecting order item data only for Data that matches the date on a specific order.
SELECT i.* FROM Orders AS o INNER JOIN OrderItems AS i WHERE o.TransactionDate = i.OrderDate AND o.OrderID = '12345';
The SELECT i.* tells the query to only return the columns of the OrderItems. And the WHERE o.TransactionDate = i.OrderDate ensures that only order items from the same date of the order with the OrderID "12345" are returned (which is defined with the AND o.OrderID = '12345'. This would work given you have a field "OrderID" on your Order table and you want to use it as a criteria.

Related

SQL - Unique results in column A based on a specific value in column B being the most frequent value

So I have the following challenge:
I'm trying to get unique results from all the clients (Column A) that made most of their purchases at store 103 (Column B).
The store is defined in the first 3 digits of the ticket number. The challenge is that I'm also getting every ticket for each client. And I just need SQL to calculate and filter the results, based on all the unique clients that made most of their purchases at store 103.
The information in Column A comes from Table 1 and the information in column B comes from Table 2.
Example
I've been trying the following:
SELECT DISTINCT Table_1.Full_Name, Table_2.Ticket_#
FROM Table_2
LEFT OUTER JOIN Table_1
ON Table_2.Customer_Number = Table_1.Customer_Number;
I know I'm missing either the group by or order by keywords, but I don't know how to use them properly in this particular case.
Thank you very much in advance.
Here are three options.
SELECT customers.Full_Name, tickets."Ticket_#"
FROM Table_2 tickets INNER JOIN Table_1 customers
ON customers.Customer_Number = tickets.Customer_Number INNER JOIN
(
SELECT Customer_Number
FROM Table_2 tickets
GROUP BY Customer_Number
HAVING COUNT(CASE WHEN LEFT("Ticket_#", 3) = '103' then 1 end)
> COUNT(CASE WHEN LEFT("Ticket_#", 3) <> '103' then 1 end)
) AS m ON m.Customer_Number = customers.Customer_Number
SELECT customers.Full_Name, tickets."Ticket_#"
FROM Table_2 tickets INNER JOIN Table_1 customers
ON customers.Customer_Number = tickets.Customer_Number
WHERE customers.Customer_Number IN (
SELECT Customer_Number
FROM Table2 tickets
WHERE "Ticket_#" LIKE '103%'
GROUP BY Customer_Number
HAVING COUNT(*) > (
SELECT COUNT(*)
FROM Table2 tickets2
WHERE tickets2.Customer_Number = tickets.Customer_Number
AND NOT "Ticket_#" LIKE '103%'
)
)
WITH data AS (
SELECT customers.Full_Name, tickets."Ticket_#"
COUNT(CASE WHEN LEFT(tickets."Ticket_#", 3) = '103' then 1 end)
OVER (PARTITION BY customers.Customer_Number) AS MatchCount
COUNT(CASE WHEN LEFT(tickets."Ticket_#", 3) <> '103' then 1 end)
OVER (PARTITION BY customers.Customer_Number) AS NonmatchCount
FROM Table_2 tickets INNER JOIN Table_1 customers
ON customers.Customer_Number = tickets.Customer_Number
)
SELECT * FROM data WHERE MatchCount > NonmatchCount;

Multiple subquery join in View with group by returns duplicate rows

I have created a view using subquery but I want this view to return few mendatory column which cant be added in group by subquery, so I have to create one more select statement and join with other group by subquery
I am come up with following query,
But problem I am facing is if group by seller has 28 rows it returns 28 duplicate rows, also I want whole query to order by TotalOrderItem.
Alter VIEW [dbo].[SellersPerformance] AS
Select
RequiredColumns.Id as Id,
aggrgateDT.SellerId as SellerId,
aggrgateDT.TenantId as TenantId,
aggrgateDT.Active as Active,
aggrgateDT.TotalOrderedItem as TotalOrderItem,
aggrgateDT.MoveToPurchase as MoveToPurchase,
aggrgateDT.GoodPurchase as GoodPurchase,
RequiredColumns.Created as Created,
RequiredColumns.Modified as Modified,
RequiredColumns.CreatorId as CreatorId,
RequiredColumns.ModifierId as ModifierId
From
(
(Select
sellerId, p.TenantId, p.Active, count(*) as TotalOrderedItem,
count(*) - count(o.Id) as MoveToPurchase,
count(o.Id) as GoodPurchase,
count(case when o.ApplicationStatus = 'Perfect' then 1 end) as Perfect,
count(case when o.ApplicationStatus = 'R-Perfect' then 1 end) as R_Perfect
FROM [dbo].[AmazonOrderPurchaseInfo] p
left join [dbo].[AmazonOrder] o
on p.AmazonOrderId = o.Id
AND p.Id = o.[AmazonOrderPurchaseInfoId]
group by SellerId, p.TenantId, p.Active
order by TotalOrderedItem offset 0 rows
) aggrgateDT
Left outer Join (
SELECT
NEWID() Id,
purchase.Created AS Created,
purchase.Modified AS Modified,
purchase.CreatorId AS CreatorId,
purchase.ModifierId AS ModifierId,
purchase.SellerId As SellerId
From dbo.AmazonOrderPurchaseInfo purchase
) RequiredColumns ON aggrgateDT.SellerId = RequiredColumns.SellerId
)
GO
You may try Group by for this.
Alter VIEW [dbo].[SellersPerformance] AS
select res.Id, res.SellerId, res.TenandId, res.Active, res.TotalOrderItem, res.MovetoPurchase, res.GoodPurchase, res.Created, res.Modified, res.CreatorId, res.ModifierId
from
(
Select
RequiredColumns.Id as Id,
aggrgateDT.SellerId as SellerId,
aggrgateDT.TenantId as TenantId,
aggrgateDT.Active as Active,
aggrgateDT.TotalOrderedItem as TotalOrderItem,
aggrgateDT.MoveToPurchase as MoveToPurchase,
aggrgateDT.GoodPurchase as GoodPurchase,
RequiredColumns.Created as Created,
RequiredColumns.Modified as Modified,
RequiredColumns.CreatorId as CreatorId,
RequiredColumns.ModifierId as ModifierId
From
(
(Select
sellerId, p.TenantId, p.Active, count(*) as TotalOrderedItem,
count(*) - count(o.Id) as MoveToPurchase,
count(o.Id) as GoodPurchase,
count(case when o.ApplicationStatus = 'Perfect' then 1 end) as Perfect,
count(case when o.ApplicationStatus = 'R-Perfect' then 1 end) as R_Perfect
FROM [dbo].[AmazonOrderPurchaseInfo] p
left join [dbo].[AmazonOrder] o
on p.AmazonOrderId = o.Id
AND p.Id = o.[AmazonOrderPurchaseInfoId]
group by SellerId, p.TenantId, p.Active
order by TotalOrderedItem offset 0 rows
) aggrgateDT
Left outer Join (
SELECT
NEWID() Id,
purchase.Created AS Created,
purchase.Modified AS Modified,
purchase.CreatorId AS CreatorId,
purchase.ModifierId AS ModifierId,
purchase.SellerId As SellerId
From dbo.AmazonOrderPurchaseInfo purchase
) RequiredColumns ON aggrgateDT.SellerId = RequiredColumns.SellerId
) as res
group by res.Id, res.SellerId, res.TenandId, res.Active, res.TotalOrderItem, res.MovetoPurchase, res.GoodPurchase, res.Created, res.Modified, res.CreatorId, res.ModifierId
)
GO
Here if Id, Created, Modified, CreatorId, ModifierId columns will have same id then you may get your expected result.

Query in SQL Server 2014 for a report (I need the last ROW of a table)

I'm using SQL Server 2014 and I have a problem with a query.
I want to have in my report, ALL the items of the order with ID_Order = 9 that have been delivered. And for the items that have been delivered at two times (Item Code = Art3 for example), I just want to have the last row, that means the last delivery of this Item, with NO repetition.
I already tried these two queries without success:
Attempt #1: DISTINCT
SELECT DISTINCT
Order.ItemCode, Delivery. Qty, Delivery.ID_Delivery,
Order.ID_Order
FROM
Delivery
INNER JOIN
Order ON Order.ID_Order = Delivery.ID_Order
WHERE
Order.ID_Order = '9'
Attempt #2: subquery
SELECT *
FROM
(SELECT
Order.ItemCode, Delivery.Qty,
FROM
Delivery
INNER JOIN
Order ON Order.ID_Order = Delivery.ID_Order
WHERE
Order.ID_Order = '9')
GROUP BY
a.ItemCode, a.Qty
Try this query --
;WITH CTE
AS (
SELECT C.ID_Order
,D.ID_Delivery
,C.ItemCode
,C.Quantity
,ROW_NUMBER() OVER (
PARTITION BY C.ItemCode ORDER BY D.ID_Delivery DESC
) AS RowNum
FROM Customer_Order C
INNER JOIN Delivery D ON C.ID_Order = D.ID_Order
AND C.ItemCode = D.ItemCode
WHERE C.ID_Order = 9
)
SELECT ID_Order
,ID_Delivery
,ItemCode
,Quantity
FROM CTE
WHERE RowNum = 1
SELECT
Order.ItemCode, Delivery. Qty, Delivery.ID_Delivery,
Order.ID_Order
FROM
Delivery
INNER JOIN
Order ON Order.ID_Order = Delivery.ID_Order
WHERE
Order.ID_Order = '9'
AND Delivery.ID_Delivery IN
(
SELECT MAX(ID_Delivery) FROM Delivery D WHERE D.ID_Order = Delivery.ID_Order GROUP BY D.ID_Order
)
I hope it will work for you.

SQL Server : bring up columns from a sub query

I am pretty stuck with this (SQL Server 2008 R2).
I have a tables called orders:
Orders:
orderid details
--------------------
1 my order
I then have a custom fields table.
Custom_fields:
rel_orderid fieldname numericvalue textvalue datevalue
-----------------------------------------------------------
1 auction 0 My auction
1 date 0 01/01/2014
I am trying to get
orderid details auction date (on one row)
-------------------------------------------------
1 my order my auction 01/01/2014
Hope that makes sense but I'm beat how to wrap up the custom_fields table into column headers and then only have 1 value (could be text value or date etc - only 1 will have data)
The auction and date and read form the fieldname column and then the values for each.
You can use max with case for this:
select o.orderid,
o.details,
max(case when c.fieldname = 'auction' then textvalue end) auction,
max(case when c.fieldname = 'date ' then datevalue end) datevalue
from orders o
join custom_fields c on o.orderid = c.rel_orderid
group by o.orderid
you can PIVOT in such a case.
select orderid,
details,
[auction],
[date]
FROM
(
select rel_orderid as orderid,
o.details,
fieldname,
(case when fieldname = 'auction'
then textvalue
when fieldname ='date'
then cast(datevalue AS varchar(128))
end) value
FROM custom_fields
INNER JOIN orders o
on o.orderid = rel_orderid
) As OrderDetails
PIVOT
(
max(value)
for fieldname in ([auction],[date])
) pvt
If you want to avoid an aggregation, you can do this using joins:
select o.orderid, o.details, a.textvalue as auction, d.datevalue as dateval
from orders o left join
custom_fields a
on a.rel_orderid = o.orderid and a.fieldname = 'auction' left join
custom_fields d
on d.rel_orderid = o.orderid and d.fieldname = 'date';
The left join gives a value (NULL) even if there is no match.

How could I combine these 3 T-SQL statements into one?

I have 3 queries that I want to combine. 1 query is for total sales, 1 is for canceled orders, and 1 is for orders that don't include specific product types. Just need the total sales $$ to output in a table format as they are now. The only thing that changes between the 3 is the where statement. Thanks!
Edit: I realize I said "Just need the total sales $$" ... what I meant was I just need the sales $$ for each query in one table. So $x, $y, $z ... x is the total sales, y is the sales dollars that got cancelled, and z is the sales dollars for the specific items.
SELECT Sum((Items.Total+Items.Shipping)*OrderDetails.Quantity) AS Total
FROM Promo INNER JOIN (Orders INNER JOIN (Items INNER JOIN OrderDetails ON Items.ItemCode = OrderDetails.ItemCode) ON Orders.OrderNumber = OrderDetails.OrderNumber) ON Promo.Promo = Orders.Promo
WHERE ((Promo.OfferType)='Sale') AND ((Items.Date) Between '6/1/2010' And '12/31/2011');
SELECT Sum((Items.Total+Items.Shipping)*OrderDetails.Quantity) AS Canceled
FROM Promo INNER JOIN (Orders INNER JOIN (Items INNER JOIN OrderDetails ON Items.ItemCode = OrderDetails.ItemCode) ON Orders.OrderNumber = OrderDetails.OrderNumber) ON Promo.Promo = Orders.Promo
WHERE (((Promo.OfferType)='Sale') AND ((Items.Date) Between '6/1/2010' And '12/31/2011') AND ((Items.Status)="Canceled"));
SELECT Sum((Items.Total+Items.Shipping)*OrderDetails.Quantity) AS BadItems
FROM Promo INNER JOIN (Orders INNER JOIN (Items INNER JOIN OrderDetails ON Items.ItemCode = OrderDetails.ItemCode) ON Orders.OrderNumber = OrderDetails.OrderNumber) ON Promo.Promo = Orders.Promo
WHERE (((Promo.OfferType)='Sale') AND ((Items.Date) Between '6/1/2010' And '12/31/2011') AND ((Items.ProductType)<>2) AND ((Items.ProductType)<>6));
Thanks!
If you want the results on 1 row:
SELECT Total, Canceled, BadItems
FROM Query1, Query2, Query3
And if you want the results in 1 column, use a UNION:
Query1
UNION
Query2
UNION
Query3
Updated to reflect question clarification:
SELECT Sum(CASE WHEN Items.Status <> 'Canceled' AND Items.ProductType = 4 THEN (Items.Total+Items.Shipping)*OrderDetails.Quantity ELSE 0 END) AS Total ,
Sum(CASE WHEN Items.Status = 'Canceled' AND Items.ProductType = 4 THEN (Items.Total+Items.Shipping)*OrderDetails.Quantity ELSE 0 END) AS Canceled,
Sum(CASE WHEN Items.ProductType <> 4 THEN (Items.Total+Items.Shipping)*OrderDetails.Quantity ELSE 0 END) AS BadItems,
FROM Promo INNER JOIN (Orders INNER JOIN (Items INNER JOIN OrderDetails ON Items.ItemCode = OrderDetails.ItemCode) ON Orders.OrderNumber = OrderDetails.OrderNumber) ON Promo.Promo = Orders.Promo
WHERE ((Promo.OfferType)='Sale') AND ((Items.Date) Between '9/1/2010' And '12/31/2010');
try to use a procedure which will accept three values as input which will suite your were statements and it will give results in one table as want. if you are stuck let me know , i will help.