I have a complex problem to solve with SQL query. I need to generate a report that gives a numerical value which represents a number of actions that users performed in each month of the year. For instance, if User1 performed the specified action in January and July, the query needs to return numbers 1 in column called 'January' and 'July' and 0 in columns that represent other month's. The table that I'm pulling the data from has only one column that contains the date and time on which the certain action was taken (this is the only column relevant to this specific problem). I need to make a SQL query that will return this informations for each user in a certain period.
Please help, and if you need any more informations please tell me and I will provide it.
Thanks
The structure of the result should be like this:
User Jan Feb ..... Dec
UID 1 0 1
I need this for every user that appears in the selected period. My application is using SQL server 2005.
select datepart(month, dateColumn) as Month
, count(*) as NumberOfActions
from Actions
group by
datepart(month, dateColumn)
The above query is correct, Though this will only return a number for the month.
I would do the following.
SELECT dateparth(month, dateColumn) as Month, count(*) as NumberOfActions
FROM Actions
GROUP BY Month
And then (if using php) consider mktime() and date() functions. Like this:
/* The year doesn't matter. we are just trying to format this in to a date */
$date = mktime(0, 0, 0, $row->Month, 1, 2012);
/* This will display 'Jan, Feb, Mar ...' respectively */
$dateText = date('M', $date);
If using another language then just google alternatives. It'll be the same principle .. just a different syntax.
Hope this helps.
This will return the data in rows but I think the OP is actually asking for it in columns. You will need a PIVOT statement for this, something like this...
Assuming...
Create Table TestPivot (UserName Varchar(10), DateColumn DateTime);
Then...
Select *
From (Select UserName, DateName(Month, DateColumn) As Month_Name, Count(*) As Month_Count
From TestPivot
Group By UserName, DateName(Month, DateColumn)) As SourcePart
Pivot (Sum(Month_Count)
For Month_Name In (January, February, March, April, May, June,
July, August, September, October, November, December)) As PivotPart
Related
I have a table in SQL Server 2012 with a month column stored as nvarchar(255):
"January", "February", "March"
And another column in this table with year stored separately as float
"2012","2013,"2014".
I do not have a day column so I want to create a combined month date column with the day starting as 1.
So for month and year fields January 2012. I want to show '2012-01-01'
How can I do such and add that into my current table?
I want to find the maximum row for a record in my table for each employee.
so for an [employee #], [month],[year]. what is latest record so for example below:
1. 102, Jan, 2019
2. 102, feb, 2019
I want to only see the second record which is the latest.
SQL Server has pretty flexible conversion to date. So, just convert the columns to a date:
select convert(date, month + ' ' + year)
You can get the maximum as:
select empid, max(convert(date, month + ' ' + year))
from t
group by empid;
If you really like, you can change the format for output purposes. I would advise you to stick with a date, though.
Note: This assumes that your internationalization settings are set to English -- which seems reasonable if you are storing month names in English.
Fix your design! The way you store data makes it really inefficient to interpret it. Here, I think the simplest option is datefromparts() and a 12-branches case expression.
Assuming that the (float) year is stored in column col_year and the (string) month is in col_month:
select t.*,
datefromparts(
cast(col_year as int),
case col_month
when 'January' then 1
when 'February' then 2
...
when 'December' then 12
end,
1
) as date_col
from mytable t
I am gathering analytics for my app. For each metric I track, I allow it to be viewed over an interval of 7, 30 or 90 days, along with grouping by date, by weekday or by time of day.
What's the best approach to handle this?
Is it possible to avoid having perform 6 different queries 6 for each metric (1 for each interval, one for each grouping)?
Example
Median conversation response time (group by day of week) Analytic(mon, tue, wed..)
Median conversation response time (group by time of day) Analytic(1 am, 2 am, 3 am..)
New conversations (group by day of week) Analytic(mon, tue, wed..)
New conversations (group by date) Analytic(20 aug, 19 aug, 18 aug etc...)
Sorry for mixing a little posgressql whit sql-server. The #... (e.g. #Param) are sql-server syntax for variable I don't know postgressql syntax for it but hopefully this will still illustrate the technique.
SELECT
date
,CASE
WHEN #Param = 'date' THEN date AS
WHEN #Param = 'dow' THEN EXTRACT(DOW FROM date)
....
ELSE
END as ParamGRoup
,SUM(amount) as TotalAmount
FROM
Table
WHERE
date BETWEEN #LowDateParam TO #HighDateParam
GROUP BY
date
,CASE
WHEN #Param = 'date' THEN date AS
WHEN #Param = 'dow' THEN EXTRACT(DOW FROM date)
....
ELSE
END as ParamGRoup
I typed this before you got your example out so I hope it is still clear. Anyway, one way you can do it is to use a case statement and then group by the same case statement. You may have to cast the THEN/Else portions of case statement as a VARCHAR or something to ensure consistent datatype if it is ever possible for it to be grouped by multiple levels but it should get you there.
I have a simple statement that starts:
SELECT a.product, MONTH(a.saledate) AS Month, Count(*) AS Total
Which yields, for example,
Product Month Total
Bike 8 1000
Please can anyone advise if it's possible to add the month's name to this query and also, is it possible to get a monthly total to appear as well?
Thanks!
The query in your example counts all the rows in your table, then presents that count next to a randomly chosen row's product and sale date. That's -- almost certainly -- not what you want. MySQL is quirky that way. Other DBMSs reject your example query.
If you want to display a monthly summary of product sold, here's the basic query:
SELECT a.product,
LAST_DAY(a.saledate) AS month_ending,
COUNT(*) AS Total
FROM table a
GROUP BY a.product, LAST_DAY(a.saledate)
The LAST_DAY() function is a great way to extract month and year from a date.
Finally, if you want to display the text name of the month, you can use the DATE_FORMAT() function to do that. %b as a format specifier gives a three-letter month name, and %M gives the full month name. So this query will do it.
SELECT a.product,
LAST_DAY(a.saledate) AS month_ending,
DATE_FORMAT(LAST_DAY(a.saledate), '%M %Y')) AS month
COUNT(*) AS Total
FROM table a
GROUP BY a.product, LAST_DAY(a.saledate)
In SQL Server 2012+ you can use the EOMONTH() function in place of LAST_DAY().
In SQL Server 2008+ you can use DATENAME(mm, a.saledate) to retrieve the month name from a date.
There are two ways of getting month name
1)
SUBSTRING('JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC ', (MONTH(a.saledate) * 4) - 3, 3)
2)
DATENAME(month, a.saledate)
Some poeple say You might be using MYSQL:
Then getting month name will be:
SELECT MONTHNAME( a.saledate);
I'm currently building a YTD report in SSRS. I'm looking to edit the default "FROM" date in a calendar selection.
I'm looking to retrieve January 1st of the previous months year. For example:
(If it's Feb 16th, 2016 .. the result should be 1/1/2016
If it's Jan 10th, 2016 .. the result should be 1/1/2015)
I built this to retrieve the current year for jan 1st, but it causes issues if we're in January because I need it to retrieve the year of the previous month (in that case it would be 2015, not 2016).
Thanks!
Try this, it should work
=DateAdd(DateInterval.Month,-1,DateSerial(Year(Today), Month(Today), 1))
UPDATE:
Based on your comment I've created this expression. It is not tested but should work.
=IIF(Today.Month>1,
DateAdd(DateInterval.Month,-1,DateSerial(Year(Today), Month(Today), 1)),
DateAdd(DateInterval.Year,-1,DateSerial(Year(Today), Month(Today), 1))
)
Let me know if this helps.
select cast(cast(year(dateadd(mm, -1,getdate())) as varchar)+'-01-01' as date)
replace getdate() with which ever field you're basing this calculation on.
for testing:
select cast(cast(year(dateadd(mm, -1,'2015-01-22')) as varchar)+'-01-01' as date)
select cast(cast(year(dateadd(mm, -1,'2016-02-01')) as varchar)+'-01-01' as date)
select cast(cast(year(dateadd(mm, -1,'2015-12-12')) as varchar)+'-01-01' as date)
We want to use Date Serial which has the forma
=DateSerial(YYYY,MM,DD)
The Month is always January
The day is always the first
If the month is January, it's last year. Otherwise, it's this year.
So, assuming we have an SSRS report with a parameter called Date , we can create a new field for your January date as follows:
=iif(Month(Parameters!Date.Value)=1,
dateserial(Year(Parameters!Date.Value)-1,1,1),
dateserial(Year(Parameters!Date.Value),1,1))
if you want to do this in the query with T-SQL (version 2012) or later:
case when month(#DATE) = 1
then DATEFROMPARTS(YEAR(#DATE)-1,1,1)
else DATEFROMPARTS(YEAR(#DATE),1,1)
end
OR, in earlier versions
CASE WHEN MONTH(#DATE) = 1
THEN CAST(CAST((YEAR(#DATE)-1)*10000 + 101 AS CHAR(8)) AS DATE)
ELSE CAST(CAST((YEAR(#DATE)*10000+ 101) AS CHAR(8)) AS DATE)
END
I have been using this query to extract information from last month
SELECT *
FROM Member
WHERE DATEPART(m, date_created) = DATEPART(m, DATEADD(m, -1, getdate()))
with the end of the year approaching, will this automatically pull Dec 2012 when i run it in Jan 2013 ?
Yes. your getdate() function will give the current date when the query is run. And you are adding -1 to the month and comparing month of date_created column and the last month. But I think you should also do comparison of year. You should add two conditions month and year both.
Yes, it will pull December data. But it will pull December data from any year, not just 2012
Yes, it will. DATEADD is a SQL internal function that adds to the full date, not just the selected part (day, month, year).