I am writing a SQL query using the AdventureWorks 2014 database.
I want to show Which orders contain more than two products? Show order number, order value, and number of products that the order contains.
I tried to write statement by itself (see below), but I'd like to be able to solve the relation :
select SalesOrderID , ProductID , LineTotal
from Sales.SalesOrderDetail
order by SalesOrderID
SELECT SalesOrderID,
COUNT(ProductID) as total_products,
SUM(LineTotal) as total_invoice
FROM SalesOrderDetail s
GROUP BY SalesOrderID
HAVING COUNT(ProductID) > 2
ORDER BY s.SalesOrderID
#Juan Carlos Oropeza
i did it can you check if there is something wrong with it
select s.SalesOrderID,
a.SalesOrderCount,
a.ProductCount,
sum(LineTotal) as OrderValue
from Sales.SalesOrderDetail s ,
(select SalesOrderID ,
count(SalesOrderID) as SalesOrderCount ,
count(productid) as ProductCount
from Sales.SalesOrderDetail
group by SalesOrderID
) a
where s.SalesOrderID = a.SalesOrderID
group by a.salesordercount, s.SalesOrderID, a.ProductCount
having a.ProductCount >2
order by s.SalesOrderID
Select
SalesOrderID,
sum(LineTotal) as [order value],
count(SalesOrderID) as [number of Product]
from Sales.SalesOrderDetail
group by SalesOrderID having count(SalesOrderID)>=2
order by SalesOrderID desc
This code would give your expected answer
SELECT SalesOrderID
,ProductID
,LineTotal
,'Sales Order ' +CAST(SalesOrderID AS VARCHAR(100))+' Contains Productid of'+CAST(ProductID AS VARCHAR(100))
AS [ProductsCountPerOrder]
,Productscount
FROM
(
SELECT salesorderid ,
productid ,
linetotal ,
Count(productid)OVER(partition BY salesorderid ORDER BY salesorderid) AS productscount
FROM sales.salesorderdetail
)dt
WHERE dt.productscount>2
ORDER BY salesorderid
Related
I have an Orders Table with an Order Date Time Field, I want to grouping the result by before and after today order date. and after that I want to sort the order after today by cusmtomer id ASC and sort the order before today by customer id DESC.
The Orders Table looks like the following image:
I tried query order before and after today and I combine the result using UNION but still not getting the result like what I want
I was tried query separately both of order before and after today. like this following code:
First I query the order after today like this:
select OrderID, CustomerID, OrderDate, ShipName, ShipCountry
from Orders
WHERE OrderDate > GETDATE() AND ShipCountry = 'USA'
ORDER BY CustomerID ASC
and the result look like this:
and then I query again like this:
select OrderID, CustomerID, OrderDate, ShipName, ShipCountry
from Orders
WHERE OrderDate < GETDATE() AND ShipCountry = 'USA'
ORDER BY CustomerID DESC
and the result look like this:
but I don't know how to joining both of two query result above with single query instead of separately query.
What I expect in my query result is combination of before today query result and after today query result.
You can Split the order by into 2 parts:
select OrderID, CustomerID, OrderDate, ShipName, ShipCountry
from Orders
WHERE ShipCountry = 'USA'
ORDER BY
(CASE WHEN OrderDate < GETDATE()
THEN CustomerID
END) DESC
, (CASE WHEN OrderDate > GETDATE()
THEN CustomerID
END) ASC
Old Ans..
select OrderID, CustomerID, OrderDate, ShipName, ShipCountry
from Orders
WHERE OrderDate <> GETDATE() AND ShipCountry = 'USA'
ORDER BY CustomerID DESC
Note:- use is not Equal to Operator for this..then you will get the
all result other than today date...
New Ans...
As you told ...you can use Order by Clause with UNION.....you need to set top records...
SELECT orders1.OrderID,orders1.CustomerID, orders1.OrderDate, orders1.ShipName, orders1.ShipCountry FROM
(
SELECT TOP 100 OrderID, CustomerID, OrderDate, ShipName, ShipCountry
from Orders
WHERE OrderDate > GETDATE() AND ShipCountry = 'USA'
ORDER BY CustomerID ASC
)orders1
UNION
SELECT orders2.OrderID, orders2.CustomerID, orders2.OrderDate, orders2.ShipName,orders2.ShipCountry FROM
(
SELECT TOP 100 OrderID, CustomerID, OrderDate, ShipName, ShipCountry
from Orders
WHERE OrderDate < GETDATE() AND ShipCountry = 'USA'
ORDER BY CustomerID DESC
)orders2
Using the northwind db on mssql, i am trying to retrieve the customer's last two order dates and calculate the time between the two orders.
So something like
select c.CompanyName, o.OrderDate, o2.OrderDate,
DateDiff(d, o.OrderDate, o2.OrderDate) as TimeElapsed
unfortunately not sure how to construct it from there.
i have something like this but it's still wrong.
select c.CompanyName, o.OrderDate, o2.OrderDate,
DateDiff(d, o.OrderDate, o2.OrderDate) as TimeElapsed
from Orders o
INNER JOIN Customers ON c.CustomerID = o.CustomerID
INNER JOIN (
select OrderID, OrderDate
FROM Orders
order by OrderDate
OFFSET 1 ROWS
FETCH NEXT 1 ROW ONLY
) as o2 ON o.OrderID = o2.OrderID;
can anyone assist.
Thank you
Northwind has been obsolete for years; even AdventureWorks has been replaced. The following uses the latter but you should be able to easily translate it to your schema. Two different approaches. The last 2 select statements are used to verify the results. Notice that customer 30099 has only one order.
set nocount on;
with cte as (select SalesOrderID, OrderDate, CustomerID, row_number () over (partition by CustomerID order by OrderDate desc) as rn
from Sales.SalesOrderHeader)
select top 10 * from cte
where rn <= 2
order by CustomerID, rn;
with cte as (select SalesOrderID, OrderDate, CustomerID, row_number () over (partition by CustomerID order by OrderDate desc) as rn
from Sales.SalesOrderHeader)
select cte.CustomerID, min(cte.OrderDate) as mindate, max(cte.OrderDate),
case when min(cte.OrderDate) = max(cte.OrderDate) then cast(null as int)
else datediff(day, min(cte.OrderDate), max(cte.OrderDate)) end as dif
from cte
where rn <= 2
group by cte.CustomerID
order by CustomerID;
with cte as (select SalesOrderID, OrderDate, CustomerID, row_number () over (partition by CustomerID order by OrderDate desc) as rn
from Sales.SalesOrderHeader)
select cte.CustomerID, minr.OrderDate as mindate, cte.OrderDate as maxdate,
datediff(day, minr.OrderDate, cte.OrderDate) as dif
from cte left join cte as minr on cte.CustomerID = minr.CustomerID and minr.rn = 2
where cte.rn = 1
order by cte.CustomerID;
select top 2 CustomerID, OrderDate from Sales.SalesOrderHeader where CustomerID = 30118 order by OrderDate desc;
select top 2 CustomerID, OrderDate from Sales.SalesOrderHeader where CustomerID = 30099 order by OrderDate desc;
I'm working on AdventureWorks2014 Database and need to retrieve client's ID's for those clients who placed orders in BOTH years 2011 and 2014. So far I have this query:
SELECT CustomerID, SalesOrderID, YEAR(OrderDate) AS 'Year'
FROM Sales.SalesOrderHeader
WHERE YEAR(OrderDate) IN (2011,2014)
HAVING COUNT(YEAR(OrderDate))=2;
When I try to run it though, I get an error:
Column 'Sales.SalesOrderHeader.CustomerID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I tried adding GROUP BY or ORDER BY, but it resulted in having an empty table. I don't necessarily need to use HAVING COUNT, it was just one idea I came up with. Is there any way to list CustomerID's that repeat themselves in 2011 and 2014? I'm stuck, maybe I'm not seeing something simple?
EDIT: I really need to have both SalesOrderID and Year selected as well, not only CustomerID. That's usually where I run into trouble.
You have to use GROUP BY CustomerID and DISTINCT keywords in the COUNT to count only one for 2014 and one for 2011 (in case if there were many orders in each year):
SELECT CustomerID
FROM Sales.SalesOrderHeader
WHERE YEAR(OrderDate) IN (2011,2014)
GROUP BY CustomerID
HAVING COUNT(DISTINCT YEAR(OrderDate))=2;
To select all orders for these customers try this:
SELECT CustomerID, SalesOrderID, YEAR(OrderDate) AS 'Year'
FROM Sales.SalesOrderHeader
WHERE CustomerID IN
(SELECT CustomerID
FROM Sales.SalesOrderHeader
WHERE YEAR(OrderDate) IN (2011,2014)
GROUP BY CustomerID
HAVING COUNT(DISTINCT YEAR(OrderDate))=2
)
Or use JOIN syntax as in #dasblinkenlight's answer.
Your query has conditions on the same columns, but the results will be in different rows. There are several ways to query for records of customers with purchases in both years, with or without GROUP BY.
Here is a straightforward way of doing it with two correlated subqueries:
SELECT CustomerID, SalesOrderID, YEAR(OrderDate) AS 'Year'
FROM Sales.SalesOrderHeader t
WHERE
EXISTS (
SELECT * FROM Sales.SalesOrderHeader h
WHERE t.CustomerID=h.CustomerID AND YEAR(OrderDate)=2011
)
AND
EXISTS (
SELECT * FROM Sales.SalesOrderHeader h
WHERE t.CustomerID=h.CustomerID AND YEAR(OrderDate)=2014
)
Here is another way that uses GROUP BY:
SELECT CustomerID, SalesOrderID, YEAR(OrderDate) AS 'Year'
FROM Sales.SalesOrderHeader t
JOIN (
SELECT CustomerID
FROM Sales.SalesOrderHeader
WHERE YEAR(OrderDate) IN (2011,2014)
GROUP BY CustomerID, YEAR(OrderDate)
HAVING COUNT(*)=2
) h ON h.CustomerID=t.CustomerID
The "nested" query, which is used to retrieve CustomerIDs of interest to us, closely resembles your query.
Try this, it will only return matching Customer ID's if they have purchased in both 2011 and 2014
SELECT S.CustomerID, S.SalesOrderID, YEAR(S.OrderDate) AS 'Year'
FROM Sales.SalesOrderHeader S
WHERE S.CustomerId IN (
SELECT DISTINCT S1.CustomerId FROM Sales.SalesOrderHeader S1
INNER JOIN Sales.SalesOrderHeader S2 ON S1.CustomerID = S2.CustomerId
WHERE YEAR(S1.OrderDate) = 2011 AND YEAR(S2.OrderDate) = 2014)
AND YEAR(S.OrderDate) IN (2011,2014)
A pretty simple way to do what you want is to use window functions:
SELECT soh.CustomerID, soh.SalesOrderID, YEAR(soh.OrderDate) AS [Year]
FROM (SELECT soh.*,
MIN(YEAR(OrderDate)) OVER () as miny,
MAX(YEAR(OrderDate)) OVER () as maxy
FROM Sales.SalesOrderHeader soh
WHERE YEAR(OrderDate) IN (2011, 2014)
) soh
WHERE miny < maxy;
I'm having trouble crafting a simple SQL query that retrieves the number of orders placed on 7/15/1998, which includes the date in the result. The label number of orders should be "OrderCount".
This is what I have got so far without success.
SELECT SUM(OrderT.CID) as OrderCount
FROM OrderT
WHERE OrderT.CID= #7/15/1998#;
Here is a screenshot of the database:
SELECT OrderDate, COUNT(OrderID) AS OrderCount
FROM OrderT
WHERE OrderDate = #1998-07-15#
GROUP BY OrderDate;
This is how:
SELECT Count(*) AS OrderCount
FROM OrderT
WHERE OrderDate = #7/15/1998#;
To include order date:
SELECT OrderDate, Count(*) AS OrderCount
FROM OrderT
GROUP BY OrderDate
HAVING OrderDate = #7/15/1998#;
This might be it:
SELECT OrderDate, COUNT(OrderID) AS OrderCount FROM OrderT WHERE OrderDate = #7/15/1998#
I'm creating an SQL statement that will return a month by month summary on sales.
The summary will list some simple columns for the date, total number of sales and the total value of sales.
However, in addition to these columns, i'd like to include 3 more that will list the months best customer by amount spent. For these columns, I need some kind of inline subquery that can return their ID, Name and the Amount they spent.
My current effort uses an inline SELECT statement, however, from my knowledge on how to implement these, you can only return one column and row per in-line statement.
To get around this with my scenario, I can of course create 3 separate in-line statements, however, besides this seeming impractical, it increases the query time more that necessary.
SELECT
DATE_FORMAT(OrderDate,'%M %Y') AS OrderMonth,
COUNT(OrderID) AS TotalOrders,
SUM(OrderTotal) AS TotalAmount,
(SELECT SUM(OrderTotal) FROM Orders WHERE DATE_FORMAT(OrderDate,'%M %Y') = OrderMonth GROUP BY OrderCustomerFK ORDER BY SUM(OrderTotal) DESC LIMIT 1) AS TotalCustomerAmount,
(SELECT OrderCustomerFK FROM Orders WHERE DATE_FORMAT(OrderDate,'%M %Y') = OrderMonth GROUP BY OrderCustomerFK ORDER BY SUM(OrderTotal) DESC LIMIT 1) AS CustomerID,
(SELECT CustomerName FROM Orders INNER JOIN Customers ON OrderCustomerFK = CustomerID WHERE DATE_FORMAT(OrderDate,'%M %Y') = OrderMonth GROUP BY OrderCustomerFK ORDER BY SUM(OrderTotal) DESC LIMIT 1) AS CustomerName
FROM Orders
GROUP BY DATE_FORMAT(OrderDate,'%m%y')
ORDER BY DATE_FORMAT(OrderDate,'%y%m') DESC
How can i better structure this query?
FULL ANSWER
After some tweaking of Dave Barkers solution, I have a final version for anyone in the future looking for help.
The solution by Dave Barker worked perfectly with the customer details, however, it made the simpler Total Sales and Total Sale Amount columns get some crazy figures.
SELECT
Y.OrderMonth, Y.TotalOrders, Y.TotalAmount,
Z.OrdCustFK, Z.CustCompany, Z.CustOrdTotal, Z.CustSalesTotal
FROM
(SELECT
OrdDate,
DATE_FORMAT(OrdDate,'%M %Y') AS OrderMonth,
COUNT(OrderID) AS TotalOrders,
SUM(OrdGrandTotal) AS TotalAmount
FROM Orders
WHERE OrdConfirmed = 1
GROUP BY DATE_FORMAT(OrdDate,'%m%y')
ORDER BY DATE_FORMAT(OrdDate,'%Y%m') DESC)
Y INNER JOIN
(SELECT
DATE_FORMAT(OrdDate,'%M %Y') AS CustMonth,
OrdCustFK,
CustCompany,
COUNT(OrderID) AS CustOrdTotal,
SUM(OrdGrandTotal) AS CustSalesTotal
FROM Orders INNER JOIN CustomerDetails ON OrdCustFK = CustomerID
WHERE OrdConfirmed = 1
GROUP BY DATE_FORMAT(OrdDate,'%m%y'), OrdCustFK
ORDER BY SUM(OrdGrandTotal) DESC)
Z ON Z.CustMonth = Y.OrderMonth
GROUP BY DATE_FORMAT(OrdDate,'%Y%m')
ORDER BY DATE_FORMAT(OrdDate,'%Y%m') DESC
Move the inline SQL to be a inner join query. So you'd have something like...
SELECT DATE_FORMAT(OrderDate,'%M %Y') AS OrderMonth, COUNT(OrderID) AS TotalOrders, SUM(OrderTotal) AS TotalAmount, Z.OrderCustomerFK, Z.CustomerName, z.OrderTotal as CustomerTotal
FROM Orders
INNER JOIN (SELECT DATE_FORMAT(OrderDate,'%M %Y') as Mon, OrderCustomerFK, CustomerName, SUM(OrderTotal) as OrderTotal
FROM Orders
GROUP BY DATE_FORMAT(OrderDate,'%M %Y'), OrderCustomerFK, CustomerName ORDER BY SUM(OrderTotal) DESC LIMIT 1) Z
ON Z.Mon = DATE_FORMAT(OrderDate,'%M %Y')
GROUP BY DATE_FORMAT(OrderDate,'%m%y'), Z.OrderCustomerFK, Z.CustomerName
ORDER BY DATE_FORMAT(OrderDate,'%y%m') DESC
You can also do something like:
SELECT
a.`y`,
( SELECT #c:=NULL ) AS `temp`,
( SELECT #d:=NULL ) AS `temp`,
( SELECT
CONCAT(#c:=b.`c`, #d:=b.`d`)
FROM `b`
ORDER BY b.`uid`
LIMIT 1 ) AS `temp`,
#c as c,
#d as d
FROM `a`
Give this a shot:
SELECT CONCAT(o.order_month, ' ', o.order_year),
o.total_orders,
o.total_amount,
x.sum_order_total,
x.ordercustomerfk,
x.customername
FROM (SELECT MONTH(t.orderdate) AS order_month,
YEAR(t.orderdate) AS order_year
COUNT(t.orderid) AS total_orders,
SUM(t.ordertotal) AS total_amount
FROM ORDERS t
GROUP BY MONTH(t.orderdate), YEAR(t.orderdate)) o
JOIN (SELECT MONTH(t.orderdate) AS ordermonth,
YEAR(t.orderdate) AS orderyear
SUM(t.ordertotal) 'sum_order_total',
t.ordercustomerfk,
c.customername
FROM ORDERS t
JOIN CUSTOMERS c ON c.customerid = o.ordercustomerfk
GROUP BY t.ordercustomerfk, MONTH(t.orderdate), YEAR(t.orderdate)) x ON x.order_month = o.order_month
AND x.order_year = o.order_year
ORDER BY o.order_year DESC, o.order_month DESC