SQL Select Same Table Multiple Sums - sql

I am trying to wrap my head round this issue and I am sure the answer exists here a million times but then I am not searching for the right question.
I have a huge sales table [SALES] and I am extracting
SELECT DISTINCT S1.[ORDER ID], S1.SUPPLIER, SUM(S1.[ORDER TOTAL]) AS SUPPLIERTOTAL
FROM [SALES] S1
LEFT JOIN
(
Select s2.[Order ID], S2.[Supplier], S2.[Supplier Colour], SUM(S2.[Order TOTAL]) AS COLOURTOTAL
FROM [SALES]
WHERE [SALES].[SALESDATE] Between '20160101' and '20170101'
) AS s2
ON s1.[Order ID] = s2.[Order ID]
I have thrown this code together as an illustration as I am not by my work PC at present. My issue is that when I do get the re-select to work it produces the correct order value from the first select.
E.G Lets say the manufacturer was Ford and the total value was 100000 over ten orders it returns the 100000 correctly however on the sub select it appears to take the total value and multiply it by the total number of rows in the table. I am trying to work out what is going on with the data and query but cannot see the issue.
The only factor if its of influence is that the table has no primary key but as I am providing referential integrity with the join didn't believe that would be the case...
Anyone able to answer or come across this issue>

A bit of guessing here, as the question is not too clear, but I think you are looking for something like this:
SELECT S1.[ORDER ID], S1.SUPPLIER, SUM(S1.[ORDER TOTAL]) AS SUPPLIERTOTAL, SUM(S2.COLOURTOTAL) as COLOURTOTAL
FROM [SALES] S1
LEFT JOIN
(
Select s2.[Order ID], S2.[Supplier], S2.[Supplier Colour], S2.[Order TOTAL] AS COLOURTOTAL
FROM [SALES]
WHERE [SALES].[SALESDATE] Between '20160101' and '20170101'
) AS s2
ON s1.[Order ID] = s2.[Order ID]
GROUP BY S1.[ORDER ID], S1.SUPPLIER

Related

Analysis of customer along time

I have the task of developing a SQL query for analysing the behaviour of a customer through time.
So, I started with two tables; a calendar table (with each year-month-day of some years), and a sales table (with an ID and a purchase date of my interest) This is the query:
SELECT [Spice Id], FORMAT([Fecha venta],'yyyyMM') AS Purchase_Date
INTO #Sale_date
FROM SALES
WHERE [Spice Id] IS NOT NULL
GROUP BY [Spice Id], [Fecha venta]
enter image description here and enter image description here
Then I use a cross join to have all dates available even though the customer has no purchase in dates, I use a where clause to limit the table as I want to. Query below
SELECT [Spice Id], year, YearMonth, Purchase_Date, (Purchase_Date) AS First_purchase, (Purchase_Date) AS Last_purchase
INTO #Sorted
FROM #calendar
CROSS JOIN #Sale_date
WHERE year > 2019
AND Purchase_Date > 202001
AND Purchase_Date < FORMAT(GETDATE(),'yyyyMM')
AND YearMonth BETWEEN purchase_date AND FORMAT(GETDATE(), 'yyyyMM')
GROUP BY
[Spice Id], Year, YearMonth, Purchase_Date
ORDER BY
[Spice Id], Year ASC, YearMonth, Purchase_date
enter image description here
Then as you can see first purchase and lastpurchase are just the same as purchase date, so I update both values with the following:
----------UPDATE MIN
UPDATE #Sorted
enter code here`SET #SORTED.First_purchase = t1.minimo
FROM #Sorted
INNER JOIN
(SELECT [SPICE ID],MIN([First_purchase]) AS minimo
FROM #Sorted
GROUP BY [Spice Id])
AS t1 on t1.[spice id] = #Sorted.[spice id]
--------------Update Max
UPDATE #Sorted
SET #SORTED.Last_purchase = t1.maximo
FROM #SORTED
INNER JOIN
(SELECT [SPICE ID],MAX([Last_purchase]) AS maximo
FROM #Sorted
where Purchase_Date <= YearMonth
GROUP BY [Spice Id])
AS t1 on t1.[spice id] = #Sorted.[spice id]
So once I updated both values I got the following result, I'll use a specific ID to be more clear:
enter image description here
AS you can see, I have some mistakes Purchase_Date is not correctly ordered, I really don't mind that much because i can drop that column and leave just Start and Last, my big trouble is with last purchase, it should change overtime and update as in the following example I don't know if you find any mistakes in my logic or a better way to get to it, I wish to see the final table as this
enter image description here
I hope it is clear enough, thank you very much for your help!!
I'm not entirely sure your desired output but the updating logic to get the first and last purchase date is entirely unneccessary. You can use something like the below to always obtain these values
min(Purchase_date) over (partition by spice_id) as first_purchase
max(Purchase_date) over (partition by spice_id) as last_purchase
If you wish for purchase date to be ordered correctly then you need to evalute your order by clause, since this is last in the clause it is ordered after the first several columns have been ordered

Access/SQL Cumulative Query wth GroupBy

I need a query that basically improves upon a query I already have. My original post was here: Access Cumulative Total by Date
The existing query is a running sum of the energy capacity online as of the end of the year. I need one that makes the same one but broken out by project type, preferably in a crosstab format.
The project capacity and online date is stored in the Projects table and the Alternative Energy Type that I need the table to be grouped by is in a different table, Project Types, and the two are related through a type ID.
I'm not very good with SQL, so I've been trying to just add in the Project Types table from the Access Query Builder, but just adding in another groupby column with the Alternative Energy Type
Original:
SELECT Year(p.[Online Date]) AS yr, (SELECT SUM(p2.[System Size AC])
FROM Projects as p2
WHERE YEAR(p2.[Online Date]) <= YEAR(p.[Online Date])
) AS running_sum
FROM Projects AS p
GROUP BY Year([Online Date]);
Modified (wrong):
SELECT Year(p.[Online Date]) AS yr, (SELECT SUM(p2.[System Size AC])
FROM Projects as p2
WHERE YEAR(p2.[Online Date]) <= YEAR(p.[Online Date])
) AS running_sum, [Project Types].[Alternative Energy Type]
FROM [Project Types] INNER JOIN Projects AS p ON [Project Types].[Type ID] = p.[Project Type]
GROUP BY Year([Online Date]), [Project Types].[Alternative Energy Type];
The results of the modified query just show the total yearly running sum with the Alterntaive Energy Types next to them. This isn't correct because it's just showing the same total over and over, nothing is broken out.
I need it to be broken out so that it answers the question "How much rooftop solar did we have as of 12/31/2015, 12/31/2016, etc and how much offsite wind did we have as of 12/31/2015, 12/31/2016, etc"
You need to add an equality to the correlated subquery by grouping field, Alternative Energy Type:
SELECT t.[Alternative Energy Type],
YEAR(p.[Online Date]) AS yr,
(SELECT SUM(subp.[System Size AC])
FROM Projects subp
INNER JOIN [Project Types] subt
ON subt.[Type ID] = subp.[Project Type]
WHERE YEAR(subp.[Online Date]) <= YEAR(p.[Online Date])
AND subt.[Alternative Energy Type] = t.[Alternative Energy Type]
) AS running_sum
FROM Projects p
INNER JOIN [Project Types] t
ON t.[Type ID] = p.[Project Type]
GROUP BY t.[Alternative Energy Type],
YEAR(p.[Online Date]);
For crosstab, first run a make-table action query since the running sum calculation will cause issues
SELECT *
INTO RunningSumTbl
FROM RunningSumQ
Then run the crosstab:
TRANSFORM Sum(q.running_sum) AS SumOfRunningSum
SELECT r.[Alternative Energy Type]
FROM RunningSumTbl r
GROUP BY r.[Alternative Energy Type]
PIVOT r.[yr];
Use PIVOT clause to subset and order columns:
PIVOT r.[yr] IN (2019, 2018, 2017, 2016, 2015)

sql distinct with multiple fields requried

I'm using Advantage Database Server by Sybase. I need to elimiate duplicate addbatch's from my report, but having trouble pulling up just distinct records. Any idea what I am missing?
here is what I am using
SELECT DISTINCT
SI.[addbatch] as [Batch#],
SI.[current account #] as [Account],
SI.[status date] as [Status Date],
SI.[SKU] as [SKU],
AC.[email address] as [Email]
FROM salesinventory SI, accounts AC
WHERE AC.[account #]=SI.[current account #] and [Status Date] > '6/1/2015'
I still get duplicate addbatch's though. I'm not sure where I am going wrong! Thanks in advance! Wasn't even sure how to google this question!
The problem is that you need to check uniqueness of a single column and that's not actually what your code is performing. Try this
SELECT *
FROM (SELECT SI.[addbatch] as [Batch#],
SI.[current account #] as [Account],
SI.[status date] as [Status Date],
ETC,
ROW_NUMBER() OVER (PARTITION BY [Batch#]) AS RowNumber
FROM salesinventory SI, accounts AC
WHERE AC.[account #]=SI.[current account #] and [Status Date] > '6/1/2015') as rec
WHERE rec.RowNumber = 1
-- The following code is generic to de-duplicate records, modify to suit your need.
select x.[Well_Name] as nameX
, x.[TestDate] as dateX
from (
SELECT count(*) as dup
,[Well_Name]
,[TestDate]enter code here
FROM [dbo].[WellTests]
group by [TestDate] ,[Well_Name] ) x
where dup > 1
If you want to have unique batch numbers in your result, you have to GROUP BY the batch field only.
Something like this should work:
SELECT
SI.[addbatch] as [Batch#],
MIN(SI.[current account #]) as [Account],
MIN(SI.[status date]) as [Status Date],
MIN(SI.[SKU]) as [SKU],
MIN(AC.[email address]) as [Email]
FROM salesinventory SI, accounts AC
WHERE AC.[account #]=SI.[current account #] and [Status Date] > '6/1/2015'
GROUP BY
SI.[addbatch]
You didn't say how you want to aggregate the other columns, just replace MIN with something that makes more sense for you, like SUM or COUNT, etc.
There is a topic about grouping in the documentation.
PS: SELECT DISTINCT is (basically) just a shorter way to GROUP BY on all columns without any aggregation.

Query using Group By, Top N and Sum

I have looked through the forum and can find a variety of examples to solve my problem but just cannot put everything together.
My situation is typical that I would like to show the Top 10 customers (Orders.[Customer Name]) by group (Shop_Lookup.ShopGroup]) for their total revenue.
I can get so far in producing the overall Top 10 regardless of ShopGroup but just cannot get my head around getting the Sub Query to work. My current code is -
SELECT TOP 10 Orders.[Customer Name],
Sum(Orders.[Actual Revenue]) AS [SumOfActual Revenue],
Orders.[This Month],
Shop_Lookup.[ShopGroup]
FROM Orders
INNER JOIN Shop_Lookup ON Orders.[ShopID] = ShopLookup.[ShopID]
WHERE ((Orders.[This Month])="current")
GROUP BY Orders.[Customer Name], Orders.[This Month], Shop_Lookup.[ShopGroup]
ORDER BY Sum(Orders.[Actual Revenue]) DESC;
Completely AIR CODED ! Proceed with caution.
You can use Sub Query to get this !
SELECT
Orders.[Customer Name],
Sum(Orders.[Actual Revenue]) AS [SumOfActual Revenue],
Orders.[This Month],
Shop_Lookup.[ShopGroup]
FROM
Orders
INNER JOIN
Shop_Lookup
ON
Orders.[ShopID] = ShopLookup.[ShopID]
WHERE
(
(Orders.[This Month] = 'Current')
AND
(Orders.ShopID IN
(SELECT
TOP 10 ShopID
FROM
Orders AS Dupe
WHERE
Dupe.ShopID = Orders.ShopID
)
)
)
GROUP BY
Orders.[Customer Name],
Orders.[This Month],
Shop_Lookup.[ShopGroup]
ORDER BY
Sum(Orders.[Actual Revenue]) DESC;
More information on Subqueries : http://allenbrowne.com/subquery-01.html

GROUPING A TABLE BASED ON MULTIPLE FIELDS

I have a table with following format
Now i am using Access and want to create a table which will provide me sum of units where Segment is commercial, at the same time I just want to sum Subregions where they are same..means MCA+MCA+MCA... Also the period should be same where we have added them..means 2013Q1 should be added too 2013Q1 only and grouped in that format.
Something like below
Thanks and Regards
The following query totals the unit while grouping on the other fields. To change the range that it totals over, you will either be adding a WHERE clause or you will change the fields that it is GROUP BY
SELECT [Sub Region], [Corporate Family], [HP Segment], [Product Category], [Period], Sum([Units])
FROM TableName
GROUP BY [Sub Region], [Corporate Family], [HP Segment], [Product Category], [Period]