SQL Query Daily Sales Per Month of a specific product - sql

I've got a query which gets the lists of customers who've made a purchase of the product for the current day
select Customer.customerName, sum(InvoiceDetail.itemPrice * InvoiceDetail.itemQuantity) as dailyPurchase from Invoice
inner join InvoiceDetail on Invoice.invoiceID = InvoiceDetail.invoiceID
inner join Customer on Invoice.customerID = Customer.customerID
inner join Item on InvoiceDetail.itemID = Item.itemID
inner join Branch on Branch.branchID = Invoice.branchID
inner join Region on Region.regionID = Branch.regionID
where
Invoice.inactive = 0 and InvoiceDetail.inactive = 0
and Item.itemTypeID = 3
and Region.regionCode = 'CR'
and cast(Invoice.invoiceDate as date) = convert(date, '01/08/2016', 103)
group by Customer.customerName
What I need is a table with a list of all the dates in the current month, listing ALL customers who have at least purchased the product ONCE. It should resemble something similar to this image here.
Any help on how to get started or a general idea of how to get the desired result, is much appreciated. Thanks!
Sample Data from Results:
customerName dailyPurchase
AGH COMMUNICATIONS 450.00
ARIEL AMARCORD SHOP 285.00
AKN COMMUNICATION 300.00
AWSDAC TELECOMMUNICATION 2850.00
BARLEY MOBILE & SERVICES 285.00
Table Structure - I'm sorry, I don't know an easier way to copy this.

First get the customers who have purchased the product atleast once this month alongwith date.
Then use pivot to get the result in the form that you want (as seen in image). Search stackoverflow for pivot in sql server, you will get good info.
Give some information about the table structure and sample data and I might be able to help you with the query to get the results.

Related

MS Access Query - Display All Rows from Original Joined Table

I need to write a query that displays ALL revenue centers for a month whether they have revenue or not. This seems like a simple request but I have seemed to hit a brick wall. Below is my SQL:
SELECT ID_ItemNominal, ItemNominal_Description, Sum(Nz([ITM_Net],0)) AS ITM_Net_Total
FROM TSub_ItmNominal LEFT JOIN (T_Invoice RIGHT JOIN T_LineItems ON T_Invoice.ITM_Reference = T_LineItems.ITM_Reference) ON TSub_ItmNominal.ID_ItemNominal = T_LineItems.ITM_Nominal
WHERE (((Year([ITM_Date]))=[report_year] Or (Year([ITM_Date])) Is Null) AND ((Month([ITM_Date]))=[report_month]))
GROUP BY TSub_ItmNominal.ID_ItemNominal, TSub_ItmNominal.ItemNominal_Description
HAVING (((TSub_ItmNominal.ID_ItemNominal) Like "4*"))
ORDER BY TSub_ItmNominal.ID_ItemNominal;
ID_ItemNominal = the Integer code for the Revenue Center
ItemNominal_Description = the description of the Revenue Center
ITM_Net = the Currency amount for the Line Item on the Invoice, to be SUM for a month total
ITM_ Date = the Date of the Invoice
My thought was to use the LEFT JOIN to say that I want to see ALL of the revenue centers, even if those records do not have any data for that month. What I get is the centers that DO have revenue for the year but DO NOT have revenue for the month are not shown / filtered out.
What the Current query provides:
40500 | Sales - Digital | $###.##
40700 | Sales - Misc | $###.##
40800 | Sales - Mail | $###.##
40900 | Sales - Clothing| $0.00
We have not done any revenue under 40900 this year so far so it shows as a result in the query. We have done revenue in 40600 this year but not for the month of April. The 40600 seems to be filtered out by the WHERE part of the query as well as any other revenue centers that we have revenue for the year but not the selected date.
I would like to see these revenue centers included in the query but show as $0.00 for the month.
Any help would be greatly appreciated, I feel like I am close but I just can't seem to get the correct results. Thank you in advance!
You could join the original table with all rows and join your query to it like
SELECT t1.ID_ItemNominal, t1.ItemNominal_Description,t2.ITM_Net_Total
FROM TSub_ItmNominal AS t1 LEFT JOIN (SELECT ID_ItemNominal, ItemNominal_Description, Sum(Nz([ITM_Net],0)) AS ITM_Net_Total
FROM TSub_ItmNominal LEFT JOIN (T_Invoice RIGHT JOIN T_LineItems ON T_Invoice.ITM_Reference = T_LineItems.ITM_Reference) ON TSub_ItmNominal.ID_ItemNominal = T_LineItems.ITM_Nominal
WHERE (((Year([ITM_Date]))=[report_year] Or (Year([ITM_Date])) Is Null) AND ((Month([ITM_Date]))=[report_month]))
GROUP BY TSub_ItmNominal.ID_ItemNominal, TSub_ItmNominal.ItemNominal_Description
HAVING (((TSub_ItmNominal.ID_ItemNominal) Like "4*")) ) AS t2 ON t1.ID_ItemNominal = t2.ID_ItemNominal
WHERE ((([t1l].[ID_ItemNominal]) Like "4*"))
ORDER BY t1.ID_ItemNominal;
Usually, when you run LEFT JOIN + WHERE you run an analogous INNER JOIN. But according to your specifications, the sub items table should be optionally joined since it can contain actual sales data not exhaustive of all revenue centers.
Therefore, run the WHERE filtering within a subquery and then have this subquery left joined to main set of revenue centers. Also, for readability below converts RIGHT JOIN to LEFT JOIN and uses table aliases instead of full table names.
SELECT main.ITM_Nominal,
main.ItemNominal_Description,
SUM(NZ(sub.[ITM_Net], 0)) AS ITM_Net_Total
FROM (T_LineItems AS main
LEFT JOIN T_Invoice AS inv
ON inv.ITM_Reference = main.ITM_Reference)
LEFT JOIN (
SELECT ID_ItemNominal, [ITM_Net]
FROM TSub_ItmNominal
WHERE ID_ItemNominal ALIKE '4%'
AND YEAR([ITM_Date]) = [report_year]
AND MONTH([ITM_Date]) = [report_month]
) AS sub
ON sub.ID_ItemNominal = main.ITM_Nominal
GROUP BY main.ITM_Nominal,
main.ItemNominal_Description
ORDER BY main.ITM_Nominal;

Access 2013 SQL, three tables, two using sum wrong results

Can someone please help me with this issue? I've scoured the Internet looking at dozens of examples, but i just can't find a solution that works.
I am using Access 2013. The problem is that I am trying to make a query that will highlight all part numbers from a supplier that either has customer back orders and/or overdue deliveries.
I am using three tables:
tbl_Inventory_Master which I require the part number, on hand stock value, and the supplier code.
For any back orders I need to join the tbl_Customer_Back_Order table as I need the count of back order lines and the sum of the back order quantity.
If the supplier has a late delivery, then I need to add the tbl_On_Order table showing the count of overdue deliveries and the sum of the overdue quantities.
The query is retrieving the data but the returned quantities are double what they should be.
SELECT
I.Inventory_Part_Num, I.Description, I.On_Hand_Stock,
COUNT (B.Part_Number) AS Back_Order_Count, SUM(B.Back_Order_Qty) as BO_Qty,
COUNT(O.Part_Number) AS Late_Deliveries_Count, SUM(O.Order_Qty) AS Late_Qty
FROM (tbl_Inventory_Master AS I
LEFT OUTER JOIN tbl_Customer_Back_Order AS B
ON I.Inventory_Part_Num = B.Part_Number)
LEFT OUTER tbl_On_Order AS O
ON I.Inventory_Part_Num = O.Part_Number
WHERE
I.Customer_Code = '274' AND
O.Due_Date < [ENTER TODAYS DATE IN FORMAT DD/MM/YYYY]
GROUP BY I.Inventory_Part_Num, I.Description, I.On_Hand_Stock
For example, for the part number 2022940 I should have 10 back order lines and an overdue quantity of 43. Instead, the query is returning 20 back order lines and an overdue quantity sum of 86.
From the on order table I have three orders totaling 144 pieces, instead the query is returning 960.
Can someone please advise, as this is driving me crazy?
You are joining along unrelated dimensions, so you need to aggregate before joining:
SELECT I.Inventory_Part_Num, I.Description, I.On_Hand_Stock,
B.Back_Order_Count, B.BO_Qty,
O.Late_Deliveries_Count, O.Late_Qty
FROM (tbl_Inventory_Master AS I LEFT OUTER JOIN
(SELECT B.Part_Number, COUNT(*) as Back_Order_Count,
SUM(B.Back_Order_Qty) as BO_Qty
FROM tbl_Customer_Back_Order AS B
GROUP BY B.Part_Number
) as B
ON I.Inventory_Part_Num = B.Part_Number
) LEFT JOIN
(SELECT O.Part_Number, COUNT(O.Part_Number) AS Late_Deliveries_Count,
SUM(O.Order_Qty) AS Late_Qty
FROM tbl_On_Order AS O
WHERE O.Due_Date < [ENTER TODAYS DATE IN FORMAT DD/MM/YYYY]
GROUP BY O.Part_Number
) as O
ON I.Inventory_Part_Num = O.Part_Number
WHERE I.Customer_Code = '274';
Notice the outer aggregation is no longer needed.

Oracle SQL Return Count of Primary key from 2 different columns in the same table

Tables
ARMASTER = Customer Information
ORDERHEAD = Sales order information (Ship to, bill to)
Hey everyone! I'm still quite new to SQL and I do belive I'm picking it up fairly quick. I have been racking my brain on this for a few hours now and have asked around the office and nobody seems to have a solution.
I'm trying to identify how many times a customer account has been used as a SHIP TO location & a BILL TO location.
SELECT ARMASTER.CUSTOMER,
ARMASTER.DIVISION,
ARMASTER.STATUS,
ARMASTER.CUHEAD AS "MASTER",
COUNT (ORDERHEAD.BILLTO) AS "COUNT_BILL",
COUNT (ORDERHEAD.SHIPTO) AS "COUNT_SHIP"
FROM ARMASTER
LEFT OUTER JOIN ORDERHEAD
ON ARMASTER.CUSTOMER = ORDERHEAD.BILLTO
LEFT OUTER JOIN ORDERHEAD
ON ARMASTER.CUSTOMER = ORDERHEAD.SHIPTO
GROUP BY ARMASTER.CUSTOMER,
ARMASTER.DIVISION,
ARMASTER.STATUS,
ARMASTER.CUHEAD
And I'm not even remotley getting what I should be getting. However, when I remove one of my joins the count is exactly what it should be for either 1 or the other of them.
Any guidance would be muchly appreciated! Thank you!
I think it can also work
SELECT CUSTOMER,
DIVISION,
STATUS,
CUHEAD AS "MASTER",
(SELECT COUNT(1) FROM ORDERHEAD WHERE SHIPTO = ARMASTER.CUSTOMER ) AS "COUNT_BILL",
(SELECT COUNT(1) FROM ORDERHEAD WHERE BILLTO = ARMASTER.CUSTOMER ) AS "COUNT_SHIP"
FROM ARMASTER

How to return 1st record from group by

Trying to return only the 1st supplier code and have all other fields unaffected.
`Select
Container.Part_Key,
Part.Part_No,
Part.Name,
Part.Revision,
Container.Quantity,
Container.Container_Status,
OP.Operation_No,
Opp.Operation_Code,
Part.Part_Status,
Supplier.Supplier_Code
From Part_v_Container as Container
Join Part_v_Part as Part
ON Part.Part_Key = Container.Part_Key
Join Part_v_Part_Operation as Op
On Op.Part_Operation_Key = Container.Part_Operation_Key
Join Part_v_Operation as OPP
On OPP.Operation_Key = OP.Operation_Key
Join part_v_approved_supplier as Approved
On Approved.part_key = container.part_key
Join common_v_Supplier as Supplier
On Supplier.supplier_no = Approved.Supplier_No
Where Container.Active = '1'
group by container.part_key`
There will be duplicate part numbers, revisions, etc. Not worried about that. I just want the part no to list only one approved supplier to the far right, even though for any given part, there are multiple approved suppliers listed in the database.
Furthermore, the order the database lists the approved suppliers does not matter.
Thanks!
Add a sub query in your select list
( select top 1 supplier.supplier_code
From supplier
Where Supplier.supplier_no = Approved.Supplier_No order by Supplier.supplier_no) as supplier code
This can be the last field in the select list
You could add An appropriate order by.
This would work in SQL Server

SQL JOIN TWO TABLES WITH GROUP BY

I am new to the world of databases etc. A developer who made my shop's POS took a large sum of money and would no longer answer me. I need to report my receivables as end end of the quarter. Please help with this query in access. I tried left join and it works fine when I join only the purchases, but not purchases and payments.
TABLES:
CUSTOMERSTABLE:
CUSTOMERID**********NAME
PURCHASESTABLE:
SALEID**********CUSTOMERID**********AMOUN******TDATE
PAYMENTSTABLE:
PAYMENTSID**********customerid*********amount******TDATE
The result should show all the customerids (with available transations or not), the total amount of purchases for each, the total amount of payments for each, the outstanding amount (net of the two), it should only consider transactions before a given TDATE
SELECT cust.customerid, Sum(purch.Amount_charged) AS totalPurchases, Sum(pay.Payment_Made) AS SumOfPayment_Made
FROM (cust INNER JOIN pay ON cust.customerid = pay.Account_Id) INNER JOIN purch ON cust.customerid = purch.Account_Id
WHERE ((([purch].[TDATE]) Between '4/6/2015' And '5/18/2015'))
GROUP BY cust.customerid;