I have a table that looks like this:
timestamp | commodity | amount | price |
I am trying to get the weighted average of a commodity ,for each day from the last 7 days(In order to create a graph, c# program), I managed to create a query to get the weighted average:
SELECT SUM(price * amount),
SUM(amount)
FROM [table_name]
WHERE (commodity = #commodity)
AND (timestamp >= #fromDate
AND timestamp <= #toDate);
So, I send this query 7 times, each time adding (-1) to the fromDate and toDate, to get the averages of last 7 days.
I would like to ask if there is a way to do this in 1 query, and if there is, if it can be implemented to get the same information of the last month.
you can use convert to date and do code as below:
SELECT convert(date, timestamp) as [Dates],
SUM(price * amount),
SUM(amount)
FROM [table_name]
WHERE (commodity = #commodity)
AND (timestamp >= #fromDate
AND timestamp <= #toDate)
GROUP BY convert(date, timestamp)
you have to group by date
SELECT SUM(price* amount),SUM(amount) FROM [table_name] WHERE (commodity = #commodity) AND (cast(timestamp as date)>= #fromDate AND cast(timestamp as date)<= #toDate)
Group By cast(timestamp as date)
You should to group your data by date:
SELECT SUM(price * amount),SUM(amount)
FROM [table_name]
WHERE (commodity = #commodity)
AND (timestamp >= #fromDate
AND timestamp <= #toDate)
GROUP BY CAST(timestamp as DATE);
To generate dates, you can use as below:
;with Datescte as (
Select top (datediff(day, #fromDate, #toDate) +1) Dt = Dateadd(day, Row_Number() over (order by (Select null))-1, #fromDate)
from master..spt_values s1, master..spt_values s2
), cte2 as (
SELECT convert(date, timestamp) as [Dates],
SUM(price * amount) as [Sum_Price_Amount],
SUM(amount) as [Sum_Amount]
FROM [table_name]
WHERE (commodity = #commodity)
AND (timestamp >= #fromDate
AND timestamp <= #toDate)
GROUP BY convert(date, timestamp)
)
Select Dt as [Dates] , Sum_Price_Amount, Sum_Amount
FROM Datescte d
LEFT JOIN cte2 d2
ON d.Dt = d2.Dates
Related
I need to select first date and last date to each series
I have the following solution using a subquery
select t1.person_id,
t1.date as start_date,
(
select max(date)
from your_table t2
where t2.date > t1.date and t2.date < ALL(
select date
from your_table t3
where t3.first = 1 and t3.date > t1.date)
) as end_date
from your_table t1
where t1.first = 1
In a month, seperate by AccountNo, all transaction that exceeds 10,000 amount within 3 days must be outputted.
This is a sample table:
AccountNo-----Date------------Amount
1-------------5/1/17----------8000
1-------------5/3/17----------1000
1-------------5/4/17----------1000
1-------------5/6/17----------1000
2-------------5/7/17----------3000
2-------------5/10/17---------2000
2-------------5/13/17---------2000
2-------------5/13/17---------3000
3-------------5/14/17---------3000
3-------------5/15/17---------3000
3-------------5/16/17---------9000
4-------------5/17/17---------1000
5-------------5/18/17---------1000
5-------------5/19/17---------1000
5-------------5/20/17---------1000
The result must be:
AccountNo-----Date------------Amount
1-------------5/1/17----------8000
1-------------5/3/17----------1000
1-------------5/4/17----------1000
2-------------5/7/17----------3000
2-------------5/10/17---------2000
2-------------5/13/17---------2000
2-------------5/13/17---------3000
3-------------5/14/17---------3000
3-------------5/15/17---------3000
3-------------5/16/17---------9000
There is a code given to me, but it's not completely working yet.
Select A.*
From YourTable A
Cross Apply (
Select RT1 = sum(case when [Date] <= B2.TstDate then [Amount] else 0 end)
,RT2 = sum(case when [Date] >= B2.TstDate then [Amount] else 0 end)
From YourTable B1
Cross Join (Select TstDate=A.[Date]) B2
Where [Date] between DateAdd(DAY,-2,A.[Date]) and DateAdd(DAY,2,A.[Date])
and Year([Date])=Year(TstDate)
and Month([Date])=Month(TstDate)
) B
Where RT1>=10000 or RT2>=10000
Common table expression: TransInfo
TransInfo is a table with account, year, month, day, amount
The main query:
The [Tmiddle] query adds a row_number based on amount per day per month per accountno
The [Tmiddle] is joined again with TransInfo to limit the results to top 3 of a month AS [Touter] where the top 3 is >= 10.000
The outer most query combines the result with a table again to gain the complete transaction information again
In short:
Filter data on top 3 amounts per day per month per year per account
Check if sum of amount >= 10.000
Show results
Query:
WITH [TransInfo] ([AccountNo], [Year], [Month], [Day], [Amount], [Rownumber])
AS
(
SELECT [AccountNo]
,[Year]
,[Month]
,[Day]
,[Amount]
,ROW_NUMBER() OVER
(
PARTITION BY [AccountNo],
[Year],
[Month]
ORDER BY [Amount] DESC
) AS [Rownumber]
FROM
(
SELECT [AccountNo]
,DATEPART(YEAR, [Date]) AS [Year]
,DATEPART(MONTH, [Date]) AS [Month]
,DATEPART(DAY, [Date]) AS [Day]
,SUM([Amount]) AS [Amount]
FROM [Test].[dbo].[Data]
GROUP BY [AccountNo],
DATEPART(MONTH, [Date]),
DATEPART(YEAR, [Date]),
DATEPART(DAY, [Date])
) AS [Tinner]
)
SELECT [Data].[AccountNo]
,[Data].[Date]
,[Data].[Amount]
FROM [Test].[dbo].[Data]
INNER JOIN
(
SELECT [TransInfo].[AccountNo]
,[TransInfo].[Year]
,[TransInfo].[Month]
,[TransInfo].[Day]
,[TransInfo].[Amount]
FROM [TransInfo]
INNER JOIN
(
SELECT [AccountNo]
,[Year]
,[Month]
FROM [TransInfo]
WHERE [TransInfo].[Rownumber] <= 3
GROUP BY [TransInfo].[AccountNo],
[TransInfo].[Year],
[TransInfo].[Month]
HAVING SUM ([TransInfo].[Amount]) >= 10000
) AS [Tmiddle]
ON [Tmiddle].[AccountNo] = [TransInfo].[AccountNo]
AND [Tmiddle].[Year] = [TransInfo].[Year]
AND [Tmiddle].[Month] = [TransInfo].[Month]
WHERE [TransInfo].[Rownumber] <= 3
) AS [Touter]
ON [Data].[AccountNo] = [TOuter].[AccountNo]
AND DATEPART(YEAR, [Data].[Date]) = [TOuter].[Year]
AND DATEPART(MONTH, [Data].[Date]) = [TOuter].[Month]
AND DATEPART(DAY, [Data].[Date]) = [TOuter].[Day]
Result: Left is query result, right is complete table
Does this work as expected? You may need to change the 2's to 3's depending on what you mean by 'within 3 days'.
SELECT DISTINCT C.*
FROM YourTable C
INNER JOIN (
SELECT a.AccountNo, a.Date
FROM YourTable a
INNER JOIN YourTable b
ON a.AccountNo = b.AccountNo
AND DATEADD(DAY, 2, a.Date) <= b.Date AND b.Date >= a.Date
GROUP BY a.AccountNo, a.Date
HAVING SUM(b.Amount) > 10000
) d
ON C.AccountNo = d.AccountNo
AND DATEADD(DAY, 2, D.Date) <= C.Date AND C.Date >= D.Date
I have a table named Leave it contains 2 rows
no=1 Leave=CL,Lnumber=2,FromDate='2015-01-10',ToDate=2015-01-11'
no=2 Leave=CL,Lnumber=2,FromDate='2015-01-12',ToDate=2015-01-13'
no=3 Leave=CL,Lnumber=2,FromDate='2015-01-15',ToDate='2015-02-16'
no=4 Leave=CL,Lnumber=2,FromDate='2015-01-31',ToDate='2015-02-01'
Here I want to get january month leave report(leave and Lnumer). How can I fetch this considering this FromDate and ToDate
The answer should be like this
Leave=CL,Lnumber=7 (for jan month)
Leave=Cl,Lnumber=1 (for feb month)
I am using MSSQL 2008. You can add extra fields if it is necessory. Thank You
I'd recommend building a calendar table (basically a tally table, but with dates). Then join your leave table to the calendar table between the from and to dates, and count the days that fall in the interval.
;with t as
(
select no=1, Leave='CL',Lnumber=2,FromDate=cast('2015-01-10' as date),ToDate=cast('2015-01-11' as date) union all
select no=2, Leave='CL',Lnumber=2,FromDate=cast('2015-01-31' as date),ToDate=cast('2015-02-01' as date)
), cal as
(
select top 10000 _date = cast(cast(row_number() over (order by (select null)) + 41000 as datetime) as date)
from sys.objects a, sys.objects b
)
select
t.Leave,
_year = datepart(year, c._date),
_month = datepart(month, c._date),
count(_date)
from t
inner join cal c
on c._date between t.FromDate and t.ToDate
group by t.Leave, datepart(year, c._date), datepart(month, c._date)
How to find week number of a date if start day is Tuesday and end day is Monday?
Here is the example criteria
Date Output
...... ..........
01-Dec-2014 (Monday) - 2014_DECEMBER_WEEK_NO_1
04-Dec-2014 (Thursday) - 2014_DECEMBER_WEEK_NO_1
29-Dec-2014 (Monday) - 2014_DECEMBER_WEEK_NO_4
30-Dec-2014 (Tuesday) - 2014_DECEMBER_WEEK_NO_5
31-Dec-2014 (Tuesday) - 2014_DECEMBER_WEEK_NO_5
I tried following query:
select CAST(UPPER(DATENAME(YEAR, #FROMDATE)) AS VARCHAR(20))
+'_'+CAST(UPPER(DATENAME(MONTH, #FROMDATE)) AS VARCHAR(20))
+'_WEEK_NO_'+CAST((DAY(#FROMDATE)
+ (DATEPART(DW, DATEADD (MONTH, DATEDIFF (MONTH, 0, #FROMDATE), 0))-1) -1)/7 + 1 AS VARCHAR(10))
This working fine if start day is Sunday and end day is Saturday.
Set your first day to Tuesday
SET DATEFIRST 2
Execute the following query
DECLARE #FROMDATE DATE='31-Dec-2014'
SELECT CAST(UPPER(DATENAME(YEAR, #FROMDATE)) AS VARCHAR(20))
+'_'+CAST(UPPER(DATENAME(MONTH, #FROMDATE)) AS VARCHAR(20))
+'_WEEK_NO_'+REPLACE(CAST((DAY(#FROMDATE)
+ (DATEPART(DW, DATEADD (MONTH, DATEDIFF (MONTH, 0, #FROMDATE), 0))-1) -1)/7 AS VARCHAR(10)),'0','1')
UPDATE
SET DATEFIRST 2
DECLARE #FROMDATE DATE='12-JAN-2015'
DECLARE #ALLDATE DATE=DATEADD(month, DATEDIFF(month, 0, #FROMDATE), 0)
DECLARE #FIRSTDATE DATE
; WITH CTE as
(
SELECT 1 RNO,CAST(#ALLDATE AS DATE) as DATES
UNION ALL
SELECT RNO+1, DATEADD(DAY,1,DATES )
FROM CTE
WHERE DATES < DATEADD(MONTH,1,#ALLDATE)
)
SELECT TOP 1 #FIRSTDATE = DATES
FROM CTE
WHERE DATEPART(W,DATES)=1
SELECT CAST(UPPER(DATENAME(YEAR, #FROMDATE)) AS VARCHAR(20))
+'_'+CAST(UPPER(DATENAME(MONTH, #FROMDATE)) AS VARCHAR(20))
+'_WEEK_NO_'+CAST((DATEDIFF(DAY,#FIRSTDATE,#FROMDATE)/7)+1 AS VARCHAR(10))
set datefirst 2
DECLARE #StartDate DATE = '2014-12-01',
#EndDate DATE = '2014-12-31',
#DayCount int
SELECT #DayCount = count(* )
FROM (SELECT TOP ( datediff(DAY,#StartDate,#EndDate) + 1 )
[Date] = dateadd(DAY,ROW_NUMBER()
OVER(ORDER BY c1.name),
DATEADD(DD,-1,#StartDate))
FROM [master].[dbo].[spt_values] c1 ) x
WHERE datepart(dw,[Date]) = 1;
select CAST(UPPER(DATENAME(YEAR, #EndDate)) AS VARCHAR(20))
+'_'+CAST(UPPER(DATENAME(MONTH, #EndDate)) AS VARCHAR(20))
+'_WEEK_NO_'+ Cast(#DayCount as varchar)
I would like to retrieve records between September 1st 2013 to September 1st 2014
My current method gets the records from September 2014 to September 2015-
But it should be September 2013 to September 2014.
What I am doing wrong is it because i am getting DateTime.Now?
int thisYear = DateTime.Now.Year;
DateTime thisYearStart = new DateTime(thisYear, 9, 1);
DateTime thisYearEnd = thisYearStart.AddYears(1).AddTicks(-1);
command.Parameters.AddWithValue("#Date1", thisYearStart);
command.Parameters.AddWithValue("#Date2", thisYearEnd);
from this how do i select a distinct records?
WITH cte AS
(
SELECT ROW_NUMBER() OVER(ORDER BY ID, Name,SName, DOB) AS ROW, *
FROM TableName
WHERE Date > #Date1 And Date < #Date2
)
SELECT * FROM cte
WHERE ROW BETWEEN 1 AND 200
Please try to use the follwoing as your startDate and endDate.
DateTime startDate = new DateTime(DateTime.Now.Year-1,9,1);
DateTime endDate = new DateTime(DateTime.Now.Year,9,1);
command.Parameters.AddWithValue("#time", startDate);
command.Parameters.AddWithValue("#time2", endDate);
Try this one for distinct
WITH cte AS
(
SELECT DISTINCT ID, ROW_NUMBER() OVER(ORDER BY ID, Name,SName, DOB) AS ROW, *
FROM TableName
WHERE Date > #Date1 And Date < #Date2
)
SELECT * FROM cte
WHERE ROW BETWEEN 1 AND 200