I've got a question for my SQL query I've got too write. It's a long time ago since I've written an query so I could use some help with mine. I've tried looking for examples but didn't find the right result. Ive written an query but its really isn't working for me..
What im trying to do is get the sum of the total power consumption for each date in my database.
My table looks like:
|HistoryProbes|
|-------------|
|id (int) pk |
|timestamp (datetime) formatted as: "yyyy-MM-ddTHH:mm:ss"|
|PowerConsumption (int)|
I've found a sample that did quite work.. But it isnt the best solution for me..
it can be found at : http://cephas.net/blog/2005/12/06/sql-server-group-by-datetime/
So far i got this working
SELECT distinct CONVERT(varchar, timestamp, 111) AS thedate
FROM HistoryProbes
I got values 25/11/2009 and 24/11/2009 but i cant manage to get the sum of the PowerConsumption
Thanks.
Something like this will give you the sum per day
DECLARE #HistoryProbes TABLE(
id INT,
timesmp DATETIME,
PowerConsumption INT
)
INSERT INTO #HistoryProbes (id,timesmp,PowerConsumption) SELECT 1, '01 Jan 2009 12:00:00',1
INSERT INTO #HistoryProbes (id,timesmp,PowerConsumption) SELECT 2, '01 Jan 2009 11:00:00',2
INSERT INTO #HistoryProbes (id,timesmp,PowerConsumption) SELECT 3, '01 Jan 2009 13:00:00',3
INSERT INTO #HistoryProbes (id,timesmp,PowerConsumption) SELECT 4, '01 Jan 2009 14:00:00',4
INSERT INTO #HistoryProbes (id,timesmp,PowerConsumption) SELECT 5, '02 Jan 2009 12:00:00',14
INSERT INTO #HistoryProbes (id,timesmp,PowerConsumption) SELECT 6, '02 Jan 2009 11:00:00',24
INSERT INTO #HistoryProbes (id,timesmp,PowerConsumption) SELECT 7, '03 Jan 2009 13:00:00',34
INSERT INTO #HistoryProbes (id,timesmp,PowerConsumption) SELECT 8, '03 Jan 2009 14:00:00',44
SELECT DATEADD(dd,0, DATEDIFF(dd,0,timesmp)),
SUM(PowerConsumption)
FROM #HistoryProbes
GROUP BY DATEADD(dd,0, DATEDIFF(dd,0,timesmp))
select CONVERT(varchar, timestamp, 111) as timestamp_by_day
, sum(PowerConsumption) as total_power
from HistoryProbes
group by CONVERT(varchar, timestamp, 111)
order by CONVERT(varchar, timestamp, 111)
Try this:
SELECT Convert(varchar, timestamp, 111) as thedate, SUM(PowerConsumption) as Total
FROM HistoryProbes
GROUP BY Convert(varchar, timestamp, 111)
I'm not sure why you need distinct in there; since you're not joining to any other tables
Related
I have a separate column for a year and month in my database table called Logs and I want to retrieve logs between 2 dates like below:
So if I say retrieve logs between 01/01/2018 to last month that is 02/01/2021 then it should retrieve all the logs but I am not getting any result with the query below:
select COUNT(*)
from Logs
where ((LogYear >= YEAR('01/01/2018') and LogMonth >=Month('01/01/2018')) and (LogYear <=YEAR('02/01/2021') and LogMonth < =Month('02/01/2021')))
Output: 0 records
When I run this query, I am getting a 0 count although I have data for all the year.
What's the issue with this query?
Sample Data:
LogID LogYear LogMonth
1 2018 1
2 2018 2
3 2018 3
4 2018 4
I am trying to retrieve data from 1-Jan-2018 to 1-February-2021.
You can't compare a date by comparing its component parts, you have to build a proper date and then compare them. Unfortunately this is unsargable i.e. unable to use indexes, you would be better of storing actual dates rather than date components.
As an aside, to avoid unexpected behaviour always use an unambiguous date format.
As you mention you are passing the values from C# just ensure you set the SqlParameter type to date not datetime to avoid any possible issues with time components.
declare #Logs table (LogId int, LogYear int, LogMonth int);
declare #StartDate date = '01 Jan 2018', #EndDate date = '01 Feb 2021';
insert into #Logs (LogID, LogYear, LogMonth)
values
(1, 2018, 1),
(2, 2018, 2),
(3, 2018, 3),
(4, 2018, 4),
(5, 2021, 2),
(6, 2021, 3);
SELECT COUNT(*)
FROM #Logs
WHERE DATEFROMPARTS(LogYear, LogMonth, 1) >= #StartDate
AND DATEFROMPARTS(LogYear, LogMonth, 1) <= #EndDate;
Sample data (tweaked to check end case) produces a result of 5 because record id 5 is in the window and id 6 isn't.
I think you need to get the date in an ordered form first, either through converting into a DATETIME or an INT.
Here an example with INT:
WITH Logs2 (ID, LogDate) AS (
SELECT ID, ((LogYear * 10000) + (LogMonth * 100) + LogDay)
FROM Logs
)
SELECT COUNT(*)
FROM Logs2
WHERE (LogDate >= 20180101) AND (LogDate < 20210201)
But of course better would be to convert the 3 columns into a DATETIME, DATETIME2 or DATETIMEOFFSET.
Try this:
DECLARE #DateFrom datetime = '01/01/2018'
, #DateTo datetime = '02/01/2021'
SELECT
COUNT(*)
FROM Logs
WHERE LTRIM(LogYear*100 + LogMonth)
BETWEEN CONVERT(varchar(6), #DateFrom , 112)
AND CONVERT(varchar(6), #DateTo , 112)
Have you checked the DATEFORMAT -> SET DATEFORMAT (Transact-SQL)
Also I suggest if possible use ISO format date values to remove any regional issues, so
where ((LogYear >= YEAR('20180101') and LogMonth >=Month('20180101')) and (LogYear <=YEAR('20210201') and LogMonth < =Month('20210201')))
select COUNT(*)
from Logs
where (LogYear between 2018 and 2020)
or (logyear=2021 and logMonth <= 2)
Right now I can only think of using the DateAdd function which is just giving me a 13 month range from March 2018 through today. So for March, I want it to return results for things that has an effective date in February 2018, in April I'll want things with effective dates in March 2018. Any idea or suggestions on how to achieve this? I think I can do this by declaring variables but thought there may have been another way that didn't involve declaring variables. TIA.
Please try this.
Declare #tbl Table(
id INT ,
[group] Varchar(50),
[index] varchar(50),
Dat DATETIME,
cases int,
closed int
)
INSERT INTO #tbl VALUES(1,'g1','g2',GETUTCDATE()-1000,250,0)
INSERT INTO #tbl VALUES(2,'g2','g3',GETUTCDATE() -100,350,370)
INSERT INTO #tbl VALUES(3,'g3','g1',GETUTCDATE()-200,330,490)
INSERT INTO #tbl VALUES(3,'g3','g1',GETUTCDATE()+10,60,50)
SELECT * FROM #tbl WHERE Dat BETWEEN DATEADD(MM,-13,GETUTCDATE()) AND GETUTCDATE()
With
DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 13, 0)
you get the 1st of the month 13 months ago.
SELECT * FROM
tablename
WHERE
datecolumn
BETWEEN DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 13, 0) AND GETDATE()
This query will insert date and count of sales in a table.
SELECT
replace(CONVERT(varchar(10), DueDate, 112),'-',''),
count( distinct sale)
FROM
sale s
JOIN
Organisation o ON s.Organisationid = o.OrganisationID
WHERE
CAST(duedate AS DATE) ='1 Jan 2015'
AND '01 Jan 2015' BETWEEN StartDateUTC AND EndDateUTC
GROUP BY
replace(CONVERT(varchar(10), DueDate, 112),'-','')
I want my query to run for each day of the month (Jan-2015) and insert the count of sales for each day in a table.
Is there a way like..
Creating a cursor OR a LOOP which keeps running with a parameter which has a starting value as 1st jan-2015 and ending value 31st-Jan-2015 and with the first run it insets the count for 1st Jan and the parameter keeps incrementing for a day with every run and finally stops after 31st jan .
And the final result should have a table with count of sales for each days of the month Jan-2015.
For example:
1stJan- 10
2nd jan -20
3rd Jan - 15
and so on and so forth till 31st Jan
I'm using SQL Server 2012
You can do this by using while loop. Use FromDate and ToDate and increment the FromDate until to reach the EndDate. Insert the result into a temp table and select the result after the loop ends from the temp table (#ResultTable).
Try some this like this.
DECLARE #FromDate DATE = '01/01/2015',
#EndDate DATE = '01/31/2015'
DECLARE #ResultTable TABLE(DueDate VARCHAR(50), Sales INT)
WHILE (#FromDate <= #endDate)
BEGIN
INSERT INTO #ResultTable
SELECT
replace(CONVERT(varchar(10), DueDate, 112),'-',''),
count( distinct sale)
FROM
sale s
JOIN
Organisation o ON s.Organisationid = o.OrganisationID
WHERE
CAST(duedate AS DATE) ='1 Jan 2015'
AND '01 Jan 2015' BETWEEN StartDateUTC AND EndDateUTC
GROUP BY
replace(CONVERT(varchar(10), DueDate, 112),'-','')
--Incrementing to next date
SELECT #FromDate = DATEADD(DAY, 1, #FromDate)
END
SELECT * FROM #ResultTable
Is there a way in SQL Server that can show the Fiscal Year (begins on October 1 and ends on September 30) from a table which has a date column (1998 to 2010). Here is what I have done:
select 'FY1999' as FY, site, count(*)
from mytable
where mydate >='10/1/1998'
and mydate <'10/1/1999'
group by site
select 'FY2000' as FY, site, count(*)
from mytable
where mydate >='10/1/1999'
and mydate <'10/1/2000'
group by site
select 'FY2001' as FY, site, count(*)
from mytable
where mydate >='10/1/2000'
and mydate <'10/1/2001'
group by site
Isn't it too much repetitive when doing this for more then 10 FY year?
Here's a single query that will give you the information you want.
SELECT DATEPART(yyyy, DATEADD(mm, 3, mydate)) AS FY, site, COUNT(*) AS row_count
FROM mytable
GROUP BY DATEPART(yyyy, DATEADD(mm, 3, mydate)), site
You can even create your user-defined function in SQL Server that takes a date argument and returns the fiscal year as an int:
CREATE FUNCTION GetFiscalYear(#TheDate date)
RETURNS int
AS
BEGIN
DECLARE #FiscalYear int
IF DATEPART(month, #TheDate) < 10
SELECT #FiscalYear = DATEPART(year, #TheDate)
ELSE
SELECT #FiscalYear = DATEPART(year, #TheDate) + 1
RETURN #FiscalYear
END
Then you can use this as, for example:
SELECT Id, ShippingDate, GetFiscalYear(ShippingDate)
FROM SomeTable
Yes, it is a bit repetitive. I'd be using DatePart and some easy to discern rules:
Fiscal year is the year of the date if the month is < 10.
Fiscal year is the year of the date + 1 if the month >= 10
This is the dynamic script for UK, April to March,
for different dates you can use as refernece,
Good Luck
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
SET #StartDate = DATEADD(dd,0, DATEDIFF(dd,0, DATEADD( mm, -(((12 + DATEPART(m, getDate())) - 4)%12), getDate() ) - datePart(d,DATEADD( mm, -(((12 + DATEPART(m, getDate())) - 4)%12),getDate() ))+1 ) )
SET #EndDate = DATEADD(SS,-1,DATEADD(mm,12,#StartDate))
SELECT #StartDate,#EndDate
Start of fiscal year:
DATEADD(MONTH, DATEDIFF(MONTH, '20100401', getdate()) / 12 * 12, '20100401')
End of Fiscal Year
DATEADD(MONTH, DATEDIFF(MONTH, '20100401', getdate()) / 12 * 12, '20110331')
Replace getdate() with your own date if required
I don't have a SQL server reference handy, but here's how I'd do it in MySQL:
select date_format (date_add(mydate, interval 92 days), 'FY%Y') as FY, site, count(*)
from mytable
group by FY, site;
There are 92 days in October, November, and December, so I've offset by that much.
Yesterday there was an answer to this question, which was subsequently deleted.
I do not know why. Was there something wrong with it?
Please don't vote this answer down, I just want to know why it was deleted.
With vigorous testing, I still can't manage to fault it. In my example, Fiscal year starts July 1.
The answer was:
SELECT SUM(value), CAST(Year(DateAdd(Month, -6, TransactionDate)) as varchar) + ' - ' + CAST(Year(DateAdd(Month, 6, TransactionDate)) as varchar) as 'FY'
FROM mytable
GROUP BY CAST(Year(DateAdd(Month, -6, mydate)) as varchar) + ' - ' + CAST(Year(DateAdd(Month, 6, mydate)) as varchar)
Here is some test Sql based on Simon's answer
DECLARE #basestartdate datetime, #baseenddate datetime
SET #basestartdate = CAST('1 April 1753' AS datetime)
SET #baseenddate = CAST('31 March 1754' AS datetime)
;
WITh TestData as
(
SELECT
CAST('1 April 2015' AS datetime) input,
CAST('1 April 2015' AS datetime) expectedstartdate,
CAST('31 March 2016' AS datetime) expectedenddate UNION SELECT
CAST('2 April 2015' AS datetime),
CAST('1 April 2015' AS datetime),
CAST('31 March 2016' AS datetime) UNION SELECT
CAST('31 December 2015' AS datetime),
CAST('1 April 2015' AS datetime),
CAST('31 March 2016' AS datetime) UNION SELECT
CAST('1 January 2016' AS datetime),
CAST('1 April 2015' AS datetime),
CAST('31 March 2016' AS datetime) UNION SELECT
CAST('28 February 2016' AS datetime),
CAST('1 April 2015' AS datetime),
CAST('31 March 2016' AS datetime) UNION SELECT
CAST('31 March 2016' AS datetime),
CAST('1 April 2015' AS datetime),
CAST('31 March 2016' AS datetime) UNION SELECT
CAST('1 April 2016' AS datetime),
CAST('1 April 2016' AS datetime),
CAST('31 March 2017' AS datetime)
),
Results AS
(
SELECT
input,
expectedstartdate,
DATEADD(MONTH,
12 * (DATEDIFF(MONTH, #basestartdate, input) / 12),
#basestartdate) startdate,
expectedenddate,
DATEADD(MONTH,
12 * (DATEDIFF(MONTH, #basestartdate, input) / 12),
#baseenddate) enddate
FROM testdata
)
SELECT
CASE
WHEN (expectedstartdate = startdate) THEN 'Pass' ELSE 'Fail'
END startdateresult,
CASE
WHEN (expectedenddate = enddate) THEN 'Pass' ELSE 'Fail'
END startdateresult
FROM results
ORDER BY input
Need to get a certain subgroup of data per day (Separated by weekday)
For example
Select weekday,bla,blabla,blablabla from dbo.blabla
where bla = #StartDate
and bla <=#endDate
I need the output to be:
Monday bla blabla blablabla
Tuesday bla blabla blablabla
If someone could help me that would be awesome.
Try to use DATENAME with DW
Something like
SELECT DATENAME(DW, GETDATE())
You can then try something like
DECLARE #Table TABLE(
VAL FLOAT,
DateVal DATETIME
)
INSERT INTO #Table SELECT 1, '01 Jan 2010'
INSERT INTO #Table SELECT 2, '02 Jan 2010'
INSERT INTO #Table SELECT 3, '03 Jan 2010'
INSERT INTO #Table SELECT 4, '08 Jan 2010'
INSERT INTO #Table SELECT 5, '09 Jan 2010'
SELECT DATENAME(DW,DateVal),
SUM(VAL)
FROM #Table
GROUP BY DATENAME(DW,DateVal)