Selecting another column from a query with a different date filter - sql

I am working with some sales data and pulling the metrics for a particular week I am defining in the filter.
However, I want to add another column (first_sale_date) to my query. This will show the first time this asin/mp combo shows up in my table regardless of the date filter I am trying to pull the other metrics for.
Because I am already
filtering by date I don't know how to look back to all of the data in the table to find it's first appearance as it is before the week I am filtering for.
select date,
,asin
,marketplace
,SUM(ordered_product_sales) as OPS
,SUM(cogs) as cogs
**,min(date) as first_sale_date**
from prod.sales
where date > '2023-01-01'
group by 1,2,3,4

you can use a correlated subquery for this
select year
,week
,asin
,marketplace
,SUM(ordered_product_sales) as OPS
,SUM(cogs) as cogs
,( SELECT MIN(date) FROM sales sal1 WHERe sal1.asin = sal.asin and sal1.marketplace = sal.marketplace) as first_sale_date
from prod.sales sal
where year = '2023' and week = '1'
group by 1,2,3,4

Related

SQL: Apply an aggregate result per day using window functions

Consider a time-series table that contains three fields time of type timestamptz, balance of type numeric, and is_spent_column of type text.
The following query generates a valid result for the last day of the given interval.
SELECT
MAX(DATE_TRUNC('DAY', (time))) as last_day,
SUM(balance) FILTER ( WHERE is_spent_column is NULL ) AS value_at_last_day
FROM tbl
2010-07-12 18681.800775017498741407984000
However, I am in need of an equivalent query based on window functions to report the total value of the column named balance for all the days up to and including the given date .
Here is what I've tried so far, but without any valid result:
SELECT
DATE_TRUNC('DAY', (time)) AS daily,
SUM(sum(balance) FILTER ( WHERE is_spent_column is NULL ) ) OVER ( ORDER BY DATE_TRUNC('DAY', (time)) ) AS total_value_per_day
FROM tbl
group by 1
order by 1 desc
2010-07-12 16050.496339044977568391974000
2010-07-11 13103.159119670350269890284000
2010-07-10 12594.525752964512456914454000
2010-07-09 12380.159588711091681327014000
2010-07-08 12178.119542536668113577014000
2010-07-07 11995.943973804127033140014000
EDIT:
Here is a sample dataset:
LINK REMOVED
The running total can be computed by applying the first query above on the entire dataset up to and including the desired day. For example, for day 2009-01-31, the result is 97.13522530000000000000, or for day 2009-01-15 when we filter time as time < '2009-01-16 00:00:00' it returns 24.446144000000000000.
What I need is an alternative query that computes the running total for each day in a single query.
EDIT 2:
Thank you all so very much for your participation and support.
The reason for differences in result sets of the queries was on the preceding ETL pipelines. Sorry for my ignorance!
Below I've provided a sample schema to test the queries.
https://www.db-fiddle.com/f/veUiRauLs23s3WUfXQu3WE/2
Now both queries given above and the query given in the answer below return the same result.
Consider calculating running total via window function after aggregating data to day level. And since you aggregate with a single condition, FILTER condition can be converted to basic WHERE:
SELECT daily,
SUM(total_balance) OVER (ORDER BY daily) AS total_value_per_day
FROM (
SELECT
DATE_TRUNC('DAY', (time)) AS daily,
SUM(balance) AS total_balance
FROM tbl
WHERE is_spent_column IS NULL
GROUP BY 1
) AS daily_agg
ORDER BY daily

To show date on which highest total price is made in ssrs

I have a table with the TotalPrice column and BookedOn column which contains a date in which a particular order was placed. I want to generate a report in SSRS that will show the date on which the highest sales were made.
There are several orders made on a particular date and I want to sum all the price and then compare in which date highest sales were made.
select top 1 CONVERT(date, BookedOn) Date, sum(TotalPrice) SumTotalPrice
from your_table_name
group by BookedOn
order by SumTotalPrice desc
I used convert because didn't know the format of your date column(whether it is datetime or date), you can use just date column otherwise

I want NAV price as per (Today date minus 1) date

I have two tables. One is NAV where product daily new price is updated. Second is TDK table where item wise stock is available.
Now I want to get a summery report as per buyer name where all product wise total will come and from table one latest price will come.
I have tried below query...
SELECT dbo.TDK.buyer, dbo.NAV.Product_Name, sum(dbo.TDK.TD_UNITS) as Units, sum(dbo.TDK.TD_AMT) as 'Amount',dbo.NAV.NAValue
FROM dbo.TDK INNER JOIN
dbo.NAV
ON dbo.TDK.Products = dbo.NAV.Product_Name
group by dbo.TDK.buyer, dbo.NAV.Product_Name, dbo.NAV.NAValue
Imnportant: Common columns in both tables...
Table one NAV has column as Products
Table two TDK has column as Product_Name
If I have NAValue 4 records for one product then this query shows 4 lines with same total.
What I need??
I want this query to show only one line with latest NAValue price.
I want display one more line with Units*NAValue (latest) as "Latest Market Value".
Please guide.
What field contains the quote date? I am assuming you have a DATIME field, quoteDate, in dbo.NAV table and my other assumption is that you only store the Date part (i.e. mid-night, time = 00:00:00).
SELECT
t.buyer,
n.Product_Name,
sum(t.TD_UNITS) as Units,
sum(t.TD_AMT) as 'Amount',
n.NAValue
FROM dbo.TDK t
INNER JOIN dbo.NAV n
ON t.Products = n.Product_Name
AND n.quoteDate > getdate()-2
group by t.buyer, n.Product_Name, n.NAValue, n.QuoteDate
GetDate() will give you the current date and time. Subtracting 2 would get it before yesterday but after the day before yesterday.
Also, add n.quoteDate in your select and group by. Even though you don't need it, in case that one day you have a day of bad data with double record in NAV table, one with midnight time and another with 6 PM time.
Your code looks like SQL Server. I think you just want APPLY:
SELECT t.buyer, n.Product_Name, t.TD_UNITS as Units, t.TD_AMT as Amount, n.NAValue
FROM dbo.TDK t CROSS APPLY
(SELECT TOP (1) n.*
FROM dbo.NAV n
WHERE t.Products = n.Product_Name
ORDER BY ?? DESC -- however you define "latest"
) n;

SSRS Report Multi Parameters (start date,end date, MeterId, Displayby)

In my SSRS report there are 4 parameters StartDate, EndDate, MeterId, & DisplayBy
Start Date: datetime datatype
EndDate : datetime datatype
MeterId : is a drop down list and this will populate based on SQL query
DisplayBy: is a drop down list and this has the following values (Hour,day,Month & year)
The Database that stores hourly values for Meters, the following are the DB table columns: (MeterId,ReadingDate,Hours,Quantity,Price)
When I select the startdate, end date and the meter Id and display i want to show report based on the startdate & enddate and then by display values.
If the display is hour, the we got display all the 24 hour values for the MeterId,Quantity, Price for the date range.
If the display is day, we got display total quantity and total price for the MeterId for that date range.
If the display is Month, we got display total quantity and total price for the MeterId for that date range.
If the display is Year, we got display total quantity and total price for the MeterId for that date range. Say for example If i select start date as 1-1-2016 and end date as 12-31-2016. My result should show 12 rows for each month with their total Quantity, Total price for that particular MeterID.
my DB table stores all the hourly values i know how to show the values on screen if the user selects the display dropdown as hour. But, dont know how to show the result for day/month/year or how to group it. Do I need to use "case" statement and if so what should i need to give on display parameters.
Please suggest your idea...
Row Grouping:
SELECT I.CustomerName, I.ReadingDate, I.IntegratedHour, I.IntegratedUsage, I.IntegratedGeneration, DATEPART(dd, I.ReadingDate) AS [Reading Day], DATEPART(mm,
I.ReadingDate) AS [Reading Month], DATEPART(yyyy, I.ReadingDate) AS [Reading Year]
FROM IntegratedHour_MV90 AS I INNER JOIN
CustRptMeterExtract AS CT ON CT.CustomerName = I.CustomerName
WHERE (I.ReadingDate >= #StartDate) AND (I.ReadingDate <= #EndDate) AND (I.CustomerName IN (#FacilityName))
Expected Result:
SSRS Current Output: Doesnot match
Depending on your layout you could set row grouping to an expression something like this
=SWITCH
(
Parameters!ReportBy.Value=1, Fields!Hour.Value,
Parameters!ReportBy.Value=2, Fields!Day.Value,
Parameters!ReportBy.Value=3, Fields!Month.Value,
Parameters!ReportBy.Value=4, Fields!Year.Value,
True, 0)
This assumes you have already have the hours/days/months/years in your dataset, if not then you would have to replace the field references with expressions to return the relevant month etc.
Based on what I can see above you'll need to add a grouping level for Customer before the group expression. Also, you Quantity expression should be a sum something like this
=SUM(FIelds!IntegratedGeneration.Value)
You may still have a problem though. I'm assuming Price is a unit price, so it does not make sense to sum that too. To get round this, you should calculate the LineValue (Qty * Price) in your dataset then change the price expression to be something like
=(SUM(FIelds!LineValue.Value)/SUM(Fields!IntegratedGeneratio‌​n.Value))
and this will give you the average price.
However, this may be slow and personally I would do the work in your dataset. Again assuming you have the months, years in your table then you could do something like this.
--DECLARE #ReportBy int = 1 -- uncomment for testing
select
MeterID, Price
, CASE #ReportBy
WHEN 1 THEN [Month]
WHEN 2 THEN [Year]
ELSE NULL
END AS GroupByColumn
INTO #t
from dbo.MyDataTable
SELECT
GroupByColumn
, SUM(Price) as Price
FROM #t
Group BY GroupByColumn
Order by GroupByColumn
This assumes your report parameter is called ReportBy, if not just swap the name out.

calculating month salary for an employee

I am working on my Database in MS Access 2010
and i Need to build a query to Calculate the month salary for each Employee
it goes like this :
Input from user , which Year
Input from user again , which Month
Show Every Employee's Salary for the Input date
There are 2 Tables in the Query : Shifts , Employees
Shifts has a field for EmployeeID and a field for Day
Day field format is : Short Date
The problem is i don't know how to access the Month and the Year only !
I know that this is completely wrong , but i wanna do something like this:
SELECT
FROM EmployeesTBL INNER JOIN ShiftsTBL ON EmployeesTBL.EmployeeID = ShiftsTBL.EmployeeID
WHERE
Year(ShiftsTBL.Day)=[Enter Year]
AND
Month(ShiftsTBL.Day)=[Enter Month]
;
What do i need to write after SELECT to get the Sum of all Shifts and divide it by number of days the emp worked
Note : in the Shifts Table , i have EntryDate and ExitDate for every shift
Access has a bunch of built in date functions. I believe Month(date) and Year(date) will give you what you need.
Something like
SELECT EmpName
FROM Employees, Shifts
WHERE Employees.EmployeeID = Shifts.EmployeeID
AND
Month(Shifts.Day) = INPUT2.VALUE
AND
Year(Shifts.Day) = INPUT1.VALUE
should get you what you want!
EDIT: Aggregation: how this works will depend on how your database is set up. I think I understand you want to sum the hours worked and divide by the number of days?
If so, you will use Sum() and Count(). And you will Group By EmployeeID
SELECT Sum(Shifts)/Count(DaysWorked) AS SumDividedByCount
FROM EmployeesTBL INNER JOIN ShiftsTBL
ON EmployeesTBL.EmployeeID = ShiftsTBL.EmployeeID
WHERE
Year(ShiftsTBL.[Day])=[Enter Year]
AND
Month(ShiftsTBL.[Day])=[Enter Month]
GROUP BY EmployeeID
I used the WHERE clause because I think the results need to be filtered before they're grouped. If the results needed to be filtered after they were grouped, the HAVING clause would be used (and would go AFTER the GROUP BY)