SSRS: Pivoting columns - reporting-services

I've got a list of raw data which is passed to SSRS from a stored procedure. I have a matrix which then pivots the data.
For example:
Raw data
WeekNumber Date
1 Mon 10th Dec
1 Tue 11th Dec
1 Wed 12th Dec
2 Mon 17th Dec
When pivoted, it becomes the following for the column names
Mon 10th Dec | Tue 11th Dec | Wed 12th Dec | Mon 17th Dec
Is it possible to have a pivot with a where condition? In this example say,
I'd want it to look like
Mon 10th Dec | Tue 11th Dec | Wed 12th Dec
and then another column with Mon 17th Dec since the WeekNumber is 2

I'm not sure I understand your question. But anyway, perhaps you could consider doing the pivot in your stored procedure as per :
http://msdn.microsoft.com/en-us/library/ms177410(v=sql.105).aspx
My secret to success when using reporting tools is to solve complex problems at the data level, rather than trying to get the reporting tool to do it.

Yes, this is not difficult.
What you are calling a pivot in SSRS is really just a column group. You can add either a filter or a parent group to your column group to filter out WeekNumber <> 2 or group above by WeekNumber. With a parent group you could get results like:
WeekNum: 1 | Total for week | |WeekNum: 2 | Total for week |
Mon 10th Dec | Tue 11th Dec | Wed 12th Dec | | |Mon 17th Dec
20 | 25 | 10 | 55 | | 15 | 15

Related

php mysql command for daily report

I have a mysql table with some entries. sample data
nid | news_date
1 | 16 July 2015, 2:31 pm
2 | 16 July 2015, 2:31 pm
3 | 17 July 2015, 12:31 pm
4 | 18 July 2015, 4:28 pm
5 | 20 July 2015, 12:31 pm
I want daily report, and i tried with this sql command
SELECT count(nid), DATE(news_date)
FROM tbl_news
GROUP BY DATE(tbl_news.news_date);
But i am getting output as
count(nid) | DATE(news_date)
5 | NULL
But i want daily record count report, Anybody help.
Please try this query:-
SELECT count(nid), news_date
FROM tbl_news
GROUP BY (STR_TO_DATE(tbl_news.news_date, '%d %M %Y')) ;
I have removed the date keyword.

STR_TO_DATE() returns invalid date

I was given a job to create a new table in the database with correct data type. Here are sample records:
RegisteredMonthYear
------------------------
May 2011
March 1998
January 2000
Before I will insert the converted value I tried to convert it using STR_TO_DATE() to check if the values are correct and the result were exactly not I want. This is my query:
SELECT RegisteredMonthYear,
STR_TO_DATE(RegisteredMonthYear, '%M %Y') NewDate,
STR_TO_DATE(CONCAT(RegisteredMonthYear, ' 01'), '%M %Y %d') newDate2,
STR_TO_DATE(RegisteredMonthYear, '%M %Y') + INTERVAL 1 DAY newDate3
FROM TableName
+---------------------+---------------------------------+--------------------------------+----------+
| REGISTEREDMONTHYEAR | NEWDATE | NEWDATE2 | NEWDATE3 |
+---------------------+---------------------------------+--------------------------------+----------+
| May 2011 | April, 30 2011 00:00:00+0000 | May, 01 2011 00:00:00+0000 | (null) |
| March 1998 | February, 28 1998 00:00:00+0000 | March, 01 1998 00:00:00+0000 | (null) |
| January 2000 | December, 31 1999 00:00:00+0000 | January, 01 2000 00:00:00+0000 | (null) |
+---------------------+---------------------------------+--------------------------------+----------+
see here for demo: http://www.sqlfiddle.com/#!2/89a67/7
As you can see, column NEWDATE is one day behind. Why are the result like this?
When I tried to concatenate 01 in the string in column NEWDATE2 the result is as expected. Going back on NEWDATE column, I tried to add one day thinking that it will give exact value in column NEWDATE3 but the result is NULL.
Any idea about this?
You can use following formula (SQLFiddle):
SELECT date(str_to_date(RegisteredMonthYear, '%M %Y'))
+ interval 1 day
FROM tablename
I have added extra DATE() call on top of STR_TO_DATE() - but it makes all the difference.
But in general I agree that this is one more really weird MySQL gotcha.
For example, in PostgreSQL, you don't need to add 1 day and you don't need extra casts, simple to_timestamp is enough:
SELECT to_timestamp('May 2011', 'Mon YYYY');
2013-05-01 00:00:00-07

MySql Daily Report

I am trying to get some help fixing my complex query. I am explaining below my situation, thanks.
I have the following two tables:
ACTIVITY TABLE:
ID USER_ID CARD_ID CLOCK
1 123 04675545 4/3/2013 1:07:06 PM
2 123 04675545 4/3/2013 2:08:06 PM
3 124 04675550 4/3/2013 2:07:06 PM
4 124 04675550 4/3/2013 4:07:06 PM
5 124 04675550 4/4/2013 10:07:06 AM
6 124 04675550 4/4/2013 2:00:00 PM
7 124 04675550 4/5/2013 4:07:06 PM
8 124 04675550 4/7/2013 8:00:00 AM
9 124 04675550 4/7/2013 5:00:00 PM
PRICE TABLE:
ID FROMTIME TOTIME PRICEPERHOUR
1 08:00:00 19:59:59 50.00
2 20:00:00 07:59:59 75.00
And the following query:
select a.user_id, date(a.clock), ABS(TIME_TO_SEC(TIMEDIFF(a.clock, b.clock))/3600)*c.PRICEPERHOUR as total from
(Select if((#rn:=#rn+1)%2=0,#rn,#rn-1) As rId, act.* from act
join (select #rn:=-1)a
order by user_Id, clock) a
inner join
(Select if((#rn1:=#rn1+1)%2=0,#rn1,#rn1-1) As rId, act.* from act
join
(select #rn1:=-1)b
order by user_Id, clock) b
ON a.rid=b.rid AND a.id <> b.id
inner join
price c
on
TIME_TO_SEC(a.clock) between TIME_TO_SEC(c.FROMTIME)
AND
TIME_TO_SEC(c.TOTIME)
group by a.user_id, date(a.clock)
And I am getting the following result:
USER_ID DATE(A.CLOCK) TOTAL
123 April, 03 2013 00:00:00+0000 50.8333
124 April, 03 2013 00:00:00+0000 100
124 April, 04 2013 00:00:00+0000 194.0833
124 April, 05 2013 00:00:00+0000 1,994.0833
124 April, 07 2013 00:00:00+0000 1,994.0833
However, I am trying to get this result instead:
USER_ID DATE(A.CLOCK) TOTAL
123 April, 03 2013 00:00:00+0000 50.8333
124 April, 03 2013 00:00:00+0000 100
124 April, 04 2013 00:00:00+0000 194.0833
124 April, 05 2013 00:00:00+0000 50
124 April, 07 2013 00:00:00+0000 450
This is part of a clock system. Each time the user check-in, one entry gets recorded on the database. A correct user behavior will be that it has always a pair record recorded. For example user_id 123 clocks at 1:07:06pm and clocks again at 2:08:06pm. However, in some situations, the user may do it just once (unpaired record on the database) and therefore it should only be charged that particular hour from the record. As an example, user 124 on day 4/5/2013.
I am trying all weekend to get this query working :(. Once I get the correct result, I will add a condition to get only one user_id also, (e.g. where user_id=124).
I think even if you manage to do this there are are some potential design pitfalls:
Can people clock in for more than 1 period per day? If so then 2 records for example
10am and 2pm could total 2hours or 4hours.
What happens if people clock in at 11pm and again at 2am?
From a quick glance I don't think your sql takes into account time periods that span across the 2 different pay rates? You should definitely include this scenario in your test data.
If I was going to implement this I would probably move the logic into code, and simplify the price table by only having one time column like:
TIME, PRICE
00:00, 75.00
08:00, 50.00
20:00, 75.00
Also if a user only has one card you may not need to have card_id and user_id in the activity table.

Header wrapping to new line when each column is smaller than its size

I have a column breakout that has a header that is rather long. The breakout always has more than one column (usually 12, one for each month).
My title is: "2012 Forecasts", so I would like it to look like this:
| 2012 Forecasts
|Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec |
The issue is that when I preview the report it looks like this:
| 2012 Forecasts
|
|Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec |
This is unacceptable formatting for this table, because there are many nested rows, which make the headers extremely large.
In experimenting for solutions, I noticed that making the length of the columns large enough to fit the string "2012 Forecasts", makes the row size down. However, by doing this my columns are way too wide.
Is there a way that I can force the column header not to wrap in this way
In the properties of the header I set CanGrow to false, and it suppressed the new line

Followup: how to model discount on items in a database?

I am building an ecommerce site and would like to offer discounts on certain items for a limited time. I would like to display how much discount we are offering per product. Hence, I need two values per product, original price and the discounted price for the given duration.
This is in followup to an answer for the question I asked
Schema:
Product
productId
Name
ProductPricing
productId (FK)
startDateTimeStamp
endDateTimeStamp
price
original price only applicable if we use approach A (comes later on)
Data:
Product:
1 | Apple
2 | Banana
T1: Dec 21, 2011: No deals at this time
ProductPricing
1 | Dec 20, 2011, 00:00 | Jan 1, 2038, 00:00 | 10$ | 10$
2 | Dec 20, 2011, 00:00 | Jan 1, 2038, 00:00 | 20$ | 20$
T2: Dec 24, 2011: Deal! Apply discount of 25% on apples from Dec 25, 14:00 - Dec 26, 14:00
Approach A.
- Query updates apple prices for the given duration
ProductPricing
1 | Dec 25, 2011, 14:00 | Dec 26, 2011, 14:00 | 7.5$| 10$
2 | Dec 20, 2011, 00:00 | Dec 25, 2038, 00:00 | 20$ | 20$
Approach B.
- Query adds another record with apple prices for the given duration
ProductPricing
1 | Dec 20, 2011, 00:00 | Jan 1, 2038, 00:00 | 10$ | 10$
2 | Dec 20, 2011, 00:00 | Dec 25, 2038, 00:00 | 20$ | 20$
1 | Dec 25, 2011, 14:00 | Dec 26, 2011, 14:00 | 7.5$| 10$
T3: Dec 27, 2011 - Options
Approach A.
At this time, the deal is expired, should I reset the endTimeStamp using a trigger ?
Approach B.
Should I delete the most recent record for the product for which the deal just expired ?
The design of the ProductPricing table allows us to never have to delete old pricing data (sometimes management wants a report based on that data). With what you have described above, you'd start like this (I changed the starting date just so it's easy to pick out that yes, this was the original price when the system went into place):
ProductPricing
1 | Jan 1, 1970, 00:00:00 | Jan 1, 2038, 00:00:00 | 10$ | 10$
Now let's say you give a discount price on your apples, and you wanted to be proactive and set up the system for when the sale was over:
ProductPricing
1 | Jan 1, 1970, 00:00:00 | Dec 20, 2011, 00:00:00 | 10$ | 10$
1 | Dec 20, 2011, 00:00:01 | Dec 26, 2011, 00:00:00 | 7.5$ | 10$
1 | Dec 26, 2011, 00:00:01 | Jan 1, 2038, 00:00:00 | 10$ | 10$
What we did here was:
Update the existing record with the 2038 timestamp, changing the endDateTimeStamp field to reflect the beginning of the sale
Insert a new record to define the sale
Insert another new record to reflect the normal price again
With no overlapping timestamps, you're guaranteed to get a single record when you query the database for your price. Thus,
SELECT p.Name, pp.price, pp.original_price
FROM Product p
INNER JOIN ProductPricing pp ON pp.productId = p.productId
WHERE NOW() BETWEEN pp.startDateTimeStamp AND pp.endDateTimeStamp
would get you a product list with current pricing.