Convert Month Number to Month Name Function on Access - sql

My good reference has been
Convert Month Number to Month Name Function in SQL
So far I have:
SELECT Detail.ItemCode, SUM(Detail.QuantityOrdered) AS Total_Quantity, Header.OrderDate
FROM Detail INNER
JOIN rHeader ON Detail.SalesOrderNo = Header.SalesOrderNo
WHERE Header.OrderDate >= dateadd("m", -4, Date())
GROUP BY Detail.ItemCode, OrderDate
ORDER BY SUM(Detail.QuantityOrdered) DESC;
It filters my results and it shows only last four months result from today's month.
I'd like to have each month's sales quantity sum, and its month to name function.
For instance:
ItemCode | 10 or October | 11 | 12 | 1
PM | 200 | 200 | 200 | 200
Update: I did try the following line of code, but my date is in the form of 12/26/2016. Is there anyway that I can play with it?? Thank you!
SELECT MonthName( month , DateAdd( month , #MonthNumber , 0 ) - 1 )

In an Access query you should be able to use the MonthName function to convert a month number (e.g., 10) into a month name (e.g., 'October').
For example, if you have a query that returns a date of birth (DOB)...
SELECT [DOB] FROM [Clients] WHERE [ID]=1
DOB
----------
1977-05-15
.. you can return the name of the month in which they were born using
SELECT MonthName(Month([DOB])) AS MonthOfBirth FROM [Clients] WHERE [ID]=1
MonthOfBirth
------------
May

Related

SQL query: get total values for each month

I have a table that stores, number of fruits sold on each day. Stores number of items sold on particular date.
CREATE TABLE data
(
code VARCHAR2(50) NOT NULL,
amount NUMBER(5) NOT NULL,
DATE VARCHAR2(50) NOT NULL,
);
Sample data
code |amount| date
------+------+------------
aple | 1 | 01/01/2010
aple | 2 | 02/02/2010
orange| 3 | 03/03/2010
orange| 4 | 04/04/2010
I need to write a query, to list out, how many apple and orange sold for jan and february?
--total apple for jan
select sum(amount) from mg.drum d where date >='01/01/2010' and cdate < '01/02/2020' and code = 'aple';
--total apple for feb
select sum(amount) from mg.drum d where date >='01/02/2010' and cdate < '01/03/2020' and code = 'aple';
--total orange for jan
select sum(amount) from mg.drum d where date >='01/01/2010' and cdate < '01/02/2020' and code = 'orange';
--total orange for feb
select sum(amount) from mg.drum d where date >='01/02/2010' and cdate < '01/03/2020' and code = 'orange';
If I need to calculate for more months, more fruits, its tedious.is there a short query to write?
Can I combine at least for the months into 1 query? So 1 query to get total for each month for 1 fruit?
You can use conditional aggregation such as
SELECT TO_CHAR("date",'MM/YYYY') AS "Month/Year",
SUM( CASE WHEN code = 'apple' THEN amount END ) AS apple_sold,
SUM( CASE WHEN code = 'orange' THEN amount END ) AS orange_sold
FROM data
WHERE "date" BETWEEN date'2020-01-01' AND date'2020-02-29'
GROUP BY TO_CHAR("date",'MM/YYYY')
where date is a reserved keyword, cannot be a column name unless quoted.
Demo
select sum(amount), //date.month
from mg.drum
group by //date.month
//data.month Here you can give experssion which will return month number or name.
If you are dealing with months, then you should include the year as well. I would recommend:
SELECT TRUNC(date, 'MON') as yyyymm, code,
SUM(amount)
FROM t
GROUP BY TRUNC(date, 'MON'), code;
You can add a WHERE clause if you want only some dates or codes.
This will return a separate row for each row that has data. That is pretty close to the results from your four queries -- but this does not return 0 values.
select to_char(date_col,'MONTH') as month, code, sum(amount)
from mg.drum
group by to_char(date_col,'MONTH'), code

SQL - Calculate relative amounts within a year from date segments

I am currently coding an existing Payroll system and I have the below problem. I need to count the Vacation days taken of one employee in one year in order to transfer them to the next. The days can be either complete, or hours in a day (e.g. 6 hour vacation from default 8 hour working day)
However the existing functionality only stores the aforementioned data in a table with columns like this.
EmployeeID | StartDate | EndDate | Hours
1 01-02-2018 04-02-2018 24
1 08-03-2018 08-03-2018 4
2 30-12-2017 04-01-2018 48
3 30-12-2018 04-01-2019 48
Now the issue is that I want to limit the dates to the previous year only. So since we have 2019, I need vacations only from 2018. Meaning records with different Start and End Year, need special handling
The result table should look like this
EmployeeID | HoursPreviousYear
1 28
2 32
3 16
I am already aware of some helpful SQL functions such as DATEDIFF() or YEAR(), but since each record is different, I would probably need to use a cursor and iterate the table. Then to pass the results to a different table, I would have create in the query and return it.
To be honest I am baffled...
I never had to use cursors before and as far as I can see, I am not sure even if I can return a table as a result (which I also need to use in a join later on). I am not sure if it is worth to continue struggling with it, but it seems that there should be an easier way.
My other option was to change the behavior of the Save button, to save 2 different records, with no overlapping years, but I cannot since we are having legacy data...
There are obviously some edge cases where this isn't thorough enough, but it should get you started.
This assumes 8 hours taken per day off, totally fails to account for date ranges that span a weekend or holiday, and wouldn't account for someone taking, say three full days off followed by a half day.
DECLARE #Year int = 2018;
SELECT
EmployeeID,
SUM(CASE WHEN StartDate < DATEFROMPARTS(#Year,1,1)
THEN DATEDIFF(DAY,DATEFROMPARTS(#Year-1,12,31),EndDate)*8
WHEN EndDate > DATEFROMPARTS(#Year,12,31)
THEN DATEDIFF(DAY,StartDate,DATEFROMPARTS(#Year+1,1,1))*8
ELSE [Hours]
END) AS HoursPreviousYear
FROM
#table
GROUP BY
EmployeeID;
+------------+-------------------+
| EmployeeID | HoursPreviousYear |
+------------+-------------------+
| 1 | 28 |
| 2 | 32 |
| 3 | 16 |
+------------+-------------------+
You can use DATEDIFF to calculate additional days for start and end date to deduct extra hours from total hours as shown in the following query-
SELECT EmployeeID,
SUM(Hours) - (SUM(StDiff)+SUM(EndDiff))*8 HoursPreviousYear
FROM
(
SELECT EmployeeID,
CONVERT(DATE, StartDate , 103) StartDate,
CONVERT(DATE, EndDate , 103) EndDate,
Hours,
CASE
WHEN YEAR(CONVERT(DATE, StartDate , 103)) = 2018 THEN 0
ELSE DATEDIFF(DD,CONVERT(DATE, StartDate , 103),CONVERT(DATE, '01-01-2018' , 103))
END StDiff,
CASE
WHEN YEAR(CONVERT(DATE, EndDate , 103)) = 2018 THEN 0
ELSE DATEDIFF(DD,CONVERT(DATE, '31-12-2018' , 103),CONVERT(DATE, EndDate , 103))
END EndDiff
FROM your_table
WHERE YEAR(CONVERT(DATE, StartDate , 103)) <= 2018
AND YEAR(CONVERT(DATE, EndDate , 103)) >= 2018
)A
GROUP BY EmployeeID

Open Ticket Count Per Day

I have a table that looks like this
id | Submit_Date | Close_Date
------------------------------
1 | 2015-02-01 | 2015-02-05
2 | 2015-02-02 | 2015-02-04
3 | 2015-02-03 | 2015-02-05
4 | 2015-02-04 | 2015-02-06
5 | 2015-02-05 | 2015-02-07
6 | 2015-02-06 | 2015-02-07
7 | 2015-02-07 | 2015-02-08
I can get a count of how many ticket were open on a particular day with this:
Select count(*) from tickets where '2015-02-05' BETWEEN Submit_Date and Close_Date
This gives me 4, but I need this count for each day of a month. I don't want to have to write 30 queries to handle this. Is there a way to capture broken down by multiple days?
I created a solution a way back using a mix of #Heinzi s solution with the trick from Generate a resultset of incrementing dates in TSQL
declare #dt datetime, #dtEnd datetime
set #dt = getdate()
set #dtEnd = dateadd(day, 100, #dt)
SELECT dates.myDate,
(SELECT COUNT(*)
FROM tickets
WHERE myDate BETWEEN Submit_Date and Close_Date
)
FROM
(select Dates_To_Checkselect dateadd(day, number, #dt) mydate
from
(select distinct number from master.dbo.spt_values
where name is null
) n
where dateadd(day, number, #dt) < #dtEnd) dates
Code is combined from memory, I don't have it in front of me so there can be some typo's
First, you'll need a table that contains each date you want to check. You can use a temporary table for that. Let's assume that this table is called Dates_To_Check and has a field myDate:
SELECT myDate,
(SELECT COUNT(*)
FROM tickets
WHERE myDate BETWEEN Submit_Date and Close_Date)
FROM Dates_To_Check
Alternatively, you can create a huge table containing every possible date and use a WHERE clause to restrict the dates to those you are interested in.
If you're in SQL Server 2012 or newer you can do this using window functions with a small trick where you add 1 to the open days -1 to the closing days and then do a running total of this amount:
select distinct date, sum(opencnt) over (order by date) from (
select
Submit_Date as date,
1 as opencnt
from
ticket
union all
select
dateadd(day, 1, Close_Date),
-1
from
ticket
) TMP
There's a dateadd + 1 day to include the close date amount to that day
You could generate the list of dates and then retrieve the count for each date in your dateset.
The cte part generates the date list since the beginning of the year (an ssumption) and the next part calculates the count from your data set.
with cte as
(select cast('2015-01-01' as date) dt // you should change this part to the correct start date
union all
select dateadd(DD,1,dt) dt from cte
where dt<getdate()
)
select count(*)
from tickets
inner join cte
on cte.dt between Submit_Date and Close_Date
group by cte.dt

Query to output data from multiple days

I have this query:
select count(distinct orderid), employeeinfo.Name
from orderinfo, employeeinfo
where preparedate = '2014-11-10'
and prepareby = employeeid
group by employeeinfo.name
It outputs data like
1 | Jeff
4 | Bob
5 | Steve
Is there a way to make this work for a date range so that I can graph the data in excel?
if I want to line graph data for every day for the month of December
I'm not sure, what's your expected output, but to get a date range, you could use:
select count(distinct orderid), employeeinfo.Name
from orderinfo, employeeinfo
where preparedate <= '2014-11-30' AND preparedate >= '2014-11-01'
and prepareby = employeeid
group by employeeinfo.name

how to count days between two dates with where conditions

i have table and it has following data:
USERID NAME DATEFROM DATETO
1 xxx 2014-05-10 2014-05-15
1 xxx 2014-05-20 2014-05-25
4 yyy 2014-04-20 2014-04-21
now i have sql query like :
select * from leave where datefrom>='2014-05-01' and dateto<='2014-05-31'
so now i want output :
userid name total_leave_days
1 xxx 12
4 yyy 2
(2014-05-10 - 2014-05-15 )=6 days
(2014-05-20 - 2014-05-25 )=6 days
total = 12 days for useid 1
(2014-04-20 - 2014-04-21)= 2 days for userid 4
how can i calculate this total days .?
Please try:
select
USERID,
NAME,
SUM(DATEDIFF(day, DATEFROM, DATETO)+1) total_leave_days
From leave
group by USERID, NAME
SQL Fiddle Demo
It's important to note that you need "+1" to emulate the expected calculations because there is an inherent assumption of ""start of day" for the Start date and "end of day" for end date - but dbms's don't think that way. a date is always stored as "start of day".
select
USERID
, name
, sum( datediff(day,DATEFROM,DATETO) + 1 ) as leave_days
from leavetable
group by
USERID
, name
produces this:
| USERID | NAME | LEAVE_DAYS |
|--------|------|------------|
| 1 | xxx | 12 |
| 4 | yyy | 2 |
see: http://sqlfiddle.com/#!3/ebe5d/1
You can use DateDiff.
SELECT UserID, Name, SUM(DATEDIFF(DAY, DateFrom, DateTo) + 1) AS total_leave_days
FROM leave
WHERE datefrom >= '2014-05-01' AND dateto <= '2014-05-31'
GROUP BY UserID, Name
The + 1 ,of course, is because DATEDIFF will return the exclusive count, where it sounds like you want the inclusive number of days.
Try this:
select userid, name, sum (1 + datediff(day,datefrom,dateto)) as total_leave_days
from leaves
where datefrom>='2014-05-01' and dateto<='2014-05-31'
group by userid, name
This will sum the total leaves per userid. Note that datediff will give you 5 days difference for the range 2014-05-10 to 2014-05-15, so we need to add 1 to the result to get 6 days i.e. range inclusive of both ends.
Demo