Wednesday, October 22, 2014

Smart and Useful are not implicit the same

This special topic is something, I do philosophy on often. Why do we see, the smartest solution looses to the less smart solution? Like why did Betamax loose to VHS? Amiga to PC? HD-DVD to Blu-ray? And so on. My conclusion is; people in generel did find the looser less useful, no matter how smart they where compared to the winner.

Our job as developers(I assume you are a developer), no matter sort of developer, is to make the life easier for somebody or some, usually in an organization. At least, making life easier a.k.a. creating value, should be rule number one, for every developer.

I believe most developers understand the business domain, for the job they are hired to do, but I don't believe it is enough. By knowing the business domain, a smart solution can be developed, but is it useful? And what are the difference of smart and useful? I can state it, by making an example of financial data which need to be presented for a CEO.

Let's say the financial data is produced with the finest practices. The code behind is clean code, full maintainable and maybe even very innovative so the data can be produced in half the time as normal. The numbers are spot on error free. The data is presented in XML, so everybody with an understanding of XSLT, can transform it any way the like. It is smart!!! At least from a developer's point of view. But is it useful from a CEO's point of view. I don't think so. For being useful to, the data could have been sent, as an Excel file to the CEO's inbox. Everyone in such position know some degree of Excel, and done completely useful, the CEO should be able to present the report for his peers without further changes. XML and transformation should not be considered CEO knowledge, but Excel could.

My point is, to develop something smart and useful, you should not only know the business domain, you should also know the recipient(s) of your solution.

A good way to know a recipient is to talk with the recipient, and recognise the person's workflow. See if the solution you create, can be easily integrated into the recipient's workflow with little impact as possible, while still solve the recipient's problem and make the life easier for this person. That would be useful. Thing you could consider in advance, could be:


  • If your recipient, are using a coperate computer, then avoid things which means something has to be installed. Sometimes installation of components, is not even possible. Often components often involves regular involvement from support. Try to target you solution to something already on the your recipient(s) computer. E.g. Microsoft office. It will give you less fuzz and frustration.

  • If possible and depending of the type of the recipient, try to push the result of your solution to the recipient. As an example, again consider a report to a CEO. He shouldn't use time on digging out a report from a system you build, it should just be mailed to him. It would fit his busy workflow better. What would be even worse, would be if the system didn't use his OS credentials for logging in as single sign on, but if he had to use a 2nd credentials for this. Then the digging would be much harder. It would have even more negative impact on his workflow.

  • Optimise your result if possible. A report example again, instead of pages full of numbers, try to optimise with graphs in the start of the report. This would point out the important faster. Numbers could be added as appendix if details are needed. Optimise the report, so it is ready for be shown at meetings. CEO it save time, his life is more easy. 

  • Maybe most importantly. As a developer you are often a minority, compared to the number of recipients of your solution. They very seldom have the knowledge and technical insight on your solution as you. They will see your solution from another perspective, and you should respect this and learn from it. It is the key to make your solution more useful.

  • The purpose of education of recipients is to have a win win situation, you have less to do while your recipients would get more value. But educating people is hard, and choose you battles wisely here. E.g. Learning business people reading XML, compared to learning them a new functionality in Excel is tedious. You will often find the urge to learn people something, when they don't have time for it. E.g. When a business man who really need some data, and you have it in XML. The issues here are, his mind is on getting data, not on learning XML, He can't speak XML with his peers, He is not interested in XML at all and so on. On the other, if you extend a tool he already knows or show a feature, so you can provide him silent with XML. Then he would properly be more keen to learn about the tool, and then the education would both help you and him.  
It was few example, but is easy to come up with more.

My examples has primarily been with reporting, but this can be transferred to what ever. The golden rule is basically to know you audience and their habits. 

Thursday, October 2, 2014

SQL Server, SSIS or SSAS: Fastest and easiest way to create a time dimension

Level: 2 where 1 is noob and 5 is totally awesome
System: SQL Server 2005 and above

One of the most vital components of a dataware house, is the time dimension. It also seems to be the part which people to have most difficulties to generate. I seen all from black magic in MS Excel to big complex SQL scripts and even fancy SSIS solutions, just to generate time dimensions.

I do believe, I have found a better solution.

My solution is this script, I have written(inspired from a script I did found on Stack Overflow). You set a start and end date, plus the granularity. My recommendation is to generate times for at least a decade. A decade with the granularity of one hour, takes less than 5 Mb of data storage and 87601 records with this script as default. A decade is generated in a few seconds.


 DECLARE @StartDate DATETIME = '2010-01-01';   
 DECLARE @EndDate DATETIME = '2019-12-31';   
   
 WITH DateTimeGenerator AS  
 (  
  SELECT @StartDate AS DateAndTime  
  UNION ALL  
  SELECT DATEADD(HOUR, 1, DateAndTime) -- Change datepart to ajust granularity, see http://msdn.microsoft.com/en-us/library/ms186819.aspx for more  
  FROM  DateTimeGenerator    
  WHERE  DateAndTime + 1 < @EndDate  
 )  
 SELECT ROW_NUMBER() OVER (ORDER BY DateAndTime) As Id,   
 DateAndTime,   
 DATEPART(HOUR, DateAndTime) AS [Hour],  
 DATEPART(DAY, DateAndTime) AS [Day],  
 DATEPART(WEEK, DateAndTime) AS [Week],  
 DATEPART(MONTH, DateAndTime) AS [Month],  
 DATEPART(QUARTER, DateAndTime) AS [Quarter],  
 DATEPART(Year, DateAndTime) AS [Year]  
 INTO DimTime  
 FROM  DateTimeGenerator  
 OPTION (MAXRECURSION 0)  

Enjoy