Comparing value to another value when using grouping - reporting-services

I'm not even sure if it's possible to do this, as SSRS has alot of limitations.
Suppose I have two entries in my SQL Table:
Name: John Doe
Value: 20
Month: January 2014
Name: John Doe
Value: 30
Month: February 2014
I'm trying to do some conditional formatting depending on if the value went up or down from the previous month.
Right now I'm grouping on Month. Is there a way to somehow compare the previous value in the grouping to the current one? Something like:
=IIF(Fields!Month.Value < (Fields!Month.Value-1) ) ...
This seems like it would just take the value of the current month and give the month before that.
Thoughts?
EDIT: After trying the 'Previous' command, it is getting closer to what I'm seeking.
However... It is comparing fields from other people. (the data is grouped by person, then by month)
For example:
Name: John Doe
Value: 20
Month: January 2014
Name: John Doe
Value: 30 - WOULD BE GREEN BECAUSE 30 > 20
Month: February 2014
Name: Steve Smith
Value: 10 - WILL SHOW RED BECAUSE 10 < 30 (different person)
Month: January 2014
Name: Steve Smith
Value: 20
Month: February 2014

You can do this with the Previous function.
Say I have data like this:
And a table based on this, grouped on month:
I have applied the following expression to one of the textboxes:
=IIf(Previous(Sum(Fields!val.Value), "monthGroup") > Sum(Fields!val.Value)
, "Red"
, "Green")
For me the expression editor showed a syntax error, but it ran fine:
You could adapt this for other formatting requirements.

Related

Find date scope from MySQL efficiently

Here is my DiscountPeriod table's structure:
id
room_id
date_from
date_last
discount
Imagine that we have discount starting 01 December 2017 and ending in in 10 December 2017.
I'm searching for date-range to see if it has discount.
So date range might be totally or partly inside some of discount periods. 3 example date-ranges for search:
From 02 December to 10 December (fully inside one of discount periods)
From 20 November to 4 December (partly inside)
From 5 December to 15 December (partly inside)
Expected for all of 3 examples above is to get discount that starts in 01 December 2017 and ends in 10 December 2017.
Currently my query takes only those results which is completely inside exact period from database.
It looks like this:
SELECT * FROM `DiscountPeriod` WHERE (`room_id`=1517) AND (`date_last` >= '2017-12-12') AND (`date_from` <= '2017-12-20');
Question is, how to fit all of 3 possible search cases into 1 query for efficient searching in MySQL database tables?
Expected result is
All of following scopes: From 02 Dec to 10 Dec, From 20 Nov to 4 Dec, From 5 Dec to 15 Dec should return back 1-10 december discount.
This looks like an overlapping range problem. If you want to return all discounts which overlap with 1-10 December 2017, then try the following query:
SELECT *
FROM DiscountPeriod
WHERE
room_id = 1517 AND
'2017-12-01' <= date_last AND '2017-12-10' >= date_from;
Here is a demo which uses your test data. All three discount ranges you suggested show up in the result set. But a range lying completely outside 1-10 December 2017 is absent, as we would expect.
Demo

Alter date into text based on month

I am trying to take a date from one column and convert it to a string into a new column. The capitalization would depend on if the month is June or July. (These are the only two months shown) I tried using the date_format() function but wasn't able to have much success with it.
invoice_date | month_due
2014-07-20 | Due in July 2014
2014-06-30 | DUE IN JUNE 2014
Based on your very little information you are giving, I would suggest the following SQL statement:
SELECT
invoice_date,
CASE MONTH(invoice_date)
WHEN 6 THEN CONCAT("DUE IN JUNE ", CONVERT(YEAR(invoice_date), char))
WHEN 7 THEN CONCAT("Due in July ", CONVERT(YEAR(invoice_date), char))
ELSE "SOME OTHER MONTH"
END month_due
FROM invoice
Here, I suppose the table name is invoice. In any case the month is anything other than 6 or 7 it will display "SOME OTHER MONTH".

MYSQL: Inserting time period OR time/moment

I want to build a little calendar system for my website.
When the user creates an appointment he can choose between a time period (like 3rd march to 7th march) and a concrete day with time/moment (like 3rd march 2016 11:00).
I want to insert this into the mysql database.
Values for inserting a time period:
date1: 3rd march 2016
date2: 7th march 2016
Values for inserting a concrete day with time:
datetime: 3rd march 2016 11:00
Now the question I stuck on: How should the table look like?
I thought on sth like this (only the columns):
id | appointment | date1 | date2 | datetime1
And when the user inserts a time period the datetime-field would be empty. But is this the way to go?
One way would be
id
appointment
startdate
starttime (empty if it is an entry for a whole day)
enddate (empty if it is a single entry without a period)
endtime (empty if it is an entry for a whole day)

MySQL query results with weekday between 2 dates

I need a query to get results from a table that has 2 columns
Column startdt (datetime), Column enddt (datetime)
there are some records with startdt 2013-07-19 and enddt 2013-07-29
I need to get the records with weekday = 1 (Tuesday)
the record with date 2013-07-19 is weekday 4 and ends 2013-07-29 which is 0
Actually i want to get the results that has for weekday Monday or another weekday.
You can check the above link for an example
http://sqlfiddle.com/#!2/a80ce/1
If you don't understand what i want to do let me explain. I have an event that starts July 15 and ends July 25. (Starts Monday and ends Thursday) The user selects one of the week days (Monday, Tuesday etc). If he select Tuesday then i want the query that will get all events that are active in Tuesday.
I already found the answer so if anyone want to check it
SELECT articleid,startdt,enddt,dayofweek(startdt), DATEDIFF(enddt,startdt) datedf
FROM events
WHERE (dayofweek(events.startdt) <= 3 AND dayofweek(events.enddt) >= 3)
OR DATEDIFF(enddt,startdt) >=6
(3 is the number of the weekday "Tuesday")
How about using the comments that other people gave you and use a query that combines both dayofweek and a simple greater/smaller/equal syntax as follows:
SELECT * FROM events where dayofweek(events.startdt) <= 6 AND dayofweek(events.enddt) >= 6
This gives the following results if the user specified a friday (= 6):
ARTICLEID STARTDT ENDDT
4 July, 12 2013 00:00:00+0000 July, 26 2013 00:00:00+0000
6 July, 16 2013 00:00:00+0000 July, 20 2013 00:00:00+0000
I do think that you are better of using dayofmonth however as this (maybe just to me) makes it clearer, possibly combining the use of both to ensure that it's active on a friday.
The OP indicates that events which are in the history should also be retrieved and as such the following query does what he wants:
SELECT * FROM events where dayofweek(events.startdt) <= 6 AND dayofweek(events.enddt) >= 6 OR DATEDIFF(enddt,startdt) >=6
How about this solution:
first you convert the day of week in format that 6 is Saturday and 7 is sunday(it's easier for me)
if(dayofweek(o.start_date) = 1, 7, dayofweek(o.start_date) -1)
after that you calc the days from the start_date needed to reach some of the weekdays
(7 - if(dayofweek(o.start_date) = 1, 7, dayofweek(o.start_date) -1)
finally you make sure that the difference in days between the two dates is no less that the above calculation
(7 - if(dayofweek(o.start_date) = 1, 7, dayofweek(o.start_date) -1) <= datediff(o.end_date, o.start_date)

Get name of day from month, year, and day

Does anyone know a way to convert a month, year, and day into the day's name for any year? Example:
function convert(day, year, month)
...
return "Monday"
end
Thanks in advance!
You can use the following method:
This method uses codes for different
months and years to speed up the
calculation of the day of the week.
You might even be able to memorize the
codes. We'll use December 16, 2482 as
an example.
Take the last 2 digits of the year. In
our example, this is 82.
Divide by 4, and drop any remainder.
82 / 4 = 20, remainder 2, so we think
"20."
Add the day of the month. In our
example, 20 + 16 = 36.
Add the month's key value, from the
following table. Jan Feb Mar Apr May
June July Aug Sept Oct Nov Dec 1 4 4
0 2 5 0 3 6 1 4 6
The month for our example is December,
with a key value of 6. 36 + 6 = 42.
If your date is in January or February
of a leap year, subtract 1. We're
using December, so we don't have to
worry about this step.
Add the century code from the
following table. (These codes are for
the Gregorian calendar. The rule's
slightly simpler for Julian dates.)
1700s 1800s 1900s 2000s 4 2 0 6
Our example year is 2482, and the
2400s aren't in the table. Luckily,
the Gregorian calendar repeats every
four hundred years. All we have to do
is add or subtract 400 until we have a
date that is in the table. 2482 - 400
= 2082, so we look at the table for the 2000s, and get the code 6. Now we
add this to our running total: 42 + 6
= 48.
Add the last two digits of the year.
48 + 82 = 130.
Divide by 7 and take the remainder.
This time, 1 means Sunday, 2 means
Monday, and so on. A remainder of 0
means Saturday.
How to calculate the day of the week
A quickl google for "day of week from date algorithm" showed up this Wikipedia article
But depending on the dates you need to work with, beware the strange history of Gregorian calendar adoption