Consider This Query:
SELECT [Order Details].OrderID,
c.CategoryName,
COUNT(c.CategoryID)
FROM [Order Details]
INNER JOIN Products p
ON p.ProductID = [Order Details].ProductID
INNER JOIN Categories c
ON c.CategoryID = p.CategoryID
GROUP BY
[Order Details].OrderID,
c.CategoryName
ORDER BY
[Order Details].OrderID
this query returns this such result (Usnig Northwind Database):
I want to use Pivot with Join to get such this result:
OrderID Condiments Produce Seafood Condiments Grains/Cereals ...
--------------------------------------------------------------------------------------
10250 1 1 1 0 0 ...
10251 1 0 0 0 2 ...
...
How I can do this?
Thanks
WITH T
AS (SELECT [Order Details].OrderID,
c.CategoryName,
c.CategoryID
FROM [Order Details]
INNER JOIN Products p
ON p.ProductID = [Order Details].ProductID
INNER JOIN Categories c
ON c.CategoryID = p.CategoryID)
SELECT *
FROM T PIVOT ( COUNT (CategoryID) FOR CategoryName IN (
[Beverages],
[Condiments],
[Confections],
[Dairy Products],
[Grains/Cereals],
[Meat/Poultry],
[Produce],
[Seafood]) ) AS pvt
ORDER BY OrderID
Related
I am using the Northwind database
For now i have tried
It is where i select the Orders of the Client
select od.ProductID from Customers c JOIN
Orders o on c.CustomerID=o.CustomerID
JOIN [Order Details] od on o.OrderID=od.OrderID
where c.CustomerID='CENTC'
And here is my solution
select distinct c.CompanyName, sum(od.ProductID) as suma from Customers c JOIN
Orders o on c.CustomerID=o.CustomerID
JOIN [Order Details] od on o.OrderID=od.OrderID
where od.ProductID = '40' or od.ProductID = '11'
group by c.CompanyName
having sum(od.ProductID)='51'
But it's a one use solution so i am not satisfied.
You can use an IN subquery for this
SELECT
c.CompanyName,
c.ContactName,
SUM(od.quantity) AS quantity
FROM Customers c
JOIN Orders o on c.CustomerID = o.CustomerID
JOIN OrderDetails od on o.OrderID = od.OrderID
WHERE od.ProductID IN (
SELECT od2.ProductID
FROM Orders o2
JOIN OrderDetails od2 on o2.OrderID = od2.OrderID
WHERE o2.CustomerID = 'CENTC'
)
GROUP BY
c.CustomerID,
c.CompanyName,
c.ContactName;
I'm trying to do something like this but got an error and can't get how to do the last WHERE in the right way?
SELECT *
FROM
(
SELECT s.SupplierID, s.CompanyName,
(SELECT COUNT(*)
FROM dbo.Orders o
LEFT JOIN dbo.[Order Details] od ON o.OrderID = od.OrderID
LEFT JOIN dbo.Products p ON od.ProductID = p.ProductID
WHERE SupplierID = s.SupplierID) AS N'Number of orders'
FROM dbo.Suppliers s
)
WHERE 'Number of orders' > 150;
This is pretty sparse on details here but I think you are just trying to find and suppliers who have more than 150 orders. You can use a query with basic aggregation here and make this a lot simpler.
SELECT s.SupplierID
, s.CompanyName
, COUNT(*)
FROM dbo.Orders o
JOIN dbo.[Order Details] od ON o.OrderID = od.OrderID
JOIN dbo.Products p ON od.ProductID = p.ProductID
join dbo.Suppliers s on s.SupplierID = p.SupplierID
group by s.SupplierID
, s.CompanyName
having count(*) > 150
You need to name the main expression with an alias.
For example, this works:
SELECT * FROM (SELECT 1 AS One) O WHERE One = 1
But this does not:
SELECT * FROM (SELECT 1 AS One) WHERE One = 1
Try this:
SELECT *
FROM
(
SELECT s.SupplierID, s.CompanyName,
(SELECT COUNT(*)
FROM dbo.Orders o
LEFT JOIN dbo.[Order Details] od ON o.OrderID = od.OrderID
LEFT JOIN dbo.Products p ON od.ProductID = p.ProductID
WHERE SupplierID = s.SupplierID) AS N'Number of orders'
FROM dbo.Suppliers s
) T
WHERE 'Number of orders' > 150;
Also, as Uueerdo puointed out, it would be better to use [Square Brackets] instead of 'Single Quotes' to name and refer to the column [Number of orders]. I believe there is a setting that determines if single quotes are allowed, but square brackets are the standard.
I want to write a query that give names of those customers only who have bought all products whose price is less than 5. Whereas, my query gives all customers who have bought even a single product whose price is less than 5.
SELECT Customers.CompanyName AS Customers
FROM Customers
INNER JOIN Orders
ON Orders.CustomerID = Customers.CustomerID
JOIN [Order Details]
ON [Order Details].OrderID = Orders.OrderID
JOIN Products
ON Products.ProductID = [Order Details].ProductID
WHERE [Order Details].ProductID IN (
SELECT Products.ProductID FROM Products WHERE Products.UnitPrice < 5
)
You can try the following:
SELECT Customers.CompanyName AS Customers
FROM Customers
INNER JOIN Orders
ON Orders.CustomerID = Customers.CustomerID
JOIN [Order Details]
ON [Order Details].OrderID = Orders.OrderID
JOIN Products
ON Products.ProductID = [Order Details].ProductID
WHERE [Order Details].ProductID IN (
SELECT Products.ProductID FROM Products WHERE Products.UnitPrice < 5)
GROUP BY CompanyName
HAVING COUNT([Order Details].ProductID) = (SELECT Count(Products.ProductID) FROM Products WHERE Products.UnitPrice < 5)
I Included the GROUP BY and Having Clause so that you can get only the customers who have bought all the products with unit price less than 5
I'm trying to rank a query by not just one count, but by two.
I want to rank customers by the order items per orders.
WITH CTE AS
(
SELECT
o.CustomerId,
COUNT(DISTINCT o.OrderId) AS OrderCount,
COUNT(oi.OrderItemId) AS OrderItemCount
FROM
OrderItem oi
INNER JOIN
Order o ON o.OrderId = oi.OrderId
WHERE
o.CategoryId = 52 -- website sales
GROUP BY
o.CustomerId
)
SELECT
cust.Code,
cust.DisplayTitle,
CTE.OrderCount,
CTE.OrderItemCount,
--AVG(CTE.OrderItemCount/CTE.OrderCount) AS SumProduct ????
FROM
CTE
INNER JOIN
Customer cust ON cust.CustomerId = CTE.CustomerId
GROUP BY
cust.Code,
cust.DisplayTitle,
CTE.OrderCount,
CTE.OrderItemCount
ORDER BY
SumProduct DESC
I'm basically trying to implement the T-SQL equivalent of SUMPRODUCT() in Excel.
SELECT
o.CustomerId,
COUNT(DISTINCT o.OrderId) AS OrderCount,
COUNT(oi.OrderItemId) AS OrderItemCount,
COUNT(oi.OrderItemId) / COUNT(DISTINCT o.OrderId) avg
FROM OrderItem oi
INNER JOIN Order o ON o.OrderId = oi.OrderId
WHERE o.CategoryId = 52 -- website sales
GROUP BY o.CustomerId
order by COUNT(oi.OrderItemId) / COUNT(DISTINCT o.OrderId) desc
Just add in the join to customer
I'm working on SQL Server 2012. Trying to Pivot table data.
I have tried below following Query,
SELECT CategoryName, 1996_Val, 1997_Val
FROM(
SELECT
Categories.CategoryName,
Sum(CONVERT(money,("Order Details".UnitPrice*Quantity*(1-Discount)/100))*100) AS Sales,
YEAR(Orders.ShippedDate) AS ShippingYear
FROM Orders
INNER JOIN [Order Details] ON Orders.OrderID = [Order Details].OrderID
INNER JOIN Products ON [Order Details].ProductID = Products.ProductID
INNER JOIN Categories ON Products.CategoryID = Categories.CategoryID
WHERE (((Orders.ShippedDate) Between '19960101' And '19971231'))
GROUP BY Categories.CategoryID, Categories.CategoryName,YEAR(Orders.ShippedDate)
)p
PIVOT
(MAX(Sales) For ShippingYear IN(1996,1997)) AS pvt
ORDER BY Categories.CategoryID
which didn't work. Please help me...
I think you got the pivot a bit wrong. I think it should look something like this:
SELECT
*
FROM
(
SELECT
Categories.CategoryName,
YEAR(Orders.ShippedDate) AS ShippingYear,
CONVERT(money,([Order Details].UnitPrice*Quantity*(1-Discount)/100))*100 as Sales
FROM
Orders
INNER JOIN [Order Details] ON Orders.OrderID = [Order Details].OrderID
INNER JOIN Products ON [Order Details].ProductID = Products.ProductID
INNER JOIN Categories ON Products.CategoryID = Categories.CategoryID
WHERE (((Orders.ShippedDate) Between '19960101' And '19971231'))
) AS SourceTable
PIVOT
(
SUM(Sales)
FOR CategoryName IN ([Confections],[Meat/Poultry],
[Beverages],[Grains/Cereals],[Seafood])
) AS pvt