Thursday, March 27, 2008

Analysis Services 2000 vs. 2005: SOLVE_ORDER

Analysis Services 2000

With Analysis Services 2000 the solve order of members defined within a query and the solve order of members in the cube are evaluated at the same time. This means that if you have a calculated member in an MDX query that has a lower solve order than a member defined in the cube then the query member would be evaluated first. For example, consider the following query.

WITH
MEMBER Time.Difference as '[Time].[1997].[Q2]-[Time].[1997].[Q1]', SOLVE_ORDER=10
SELECT
{Measures.[Store Sales Ratio]} on 0,
{Time.Difference, [Time].[1997].[Q2], [Time].[1997].[Q1]} on 1

FROM
Sales

Where [Store Sales Ratio] is defined as '[Measures].[Store Sales Net]/[Measures].[Store Sales]' in the cube and given a SOLVE_ORDER of 100.


Store Sales Ratio

Difference

0.6

Q2

0.6

Q1

0.6


Looking at these results, you may expect Difference to evaluate to 0, since the Q2 value minus the Q2 difference should be subtracting the two ratios. Since the [Store Sales Ratio] solve order is higher, however, it is evaluated after the [Difference] calculation, i.e.

(( [Unit Sales], Q2 ) – ( [Unit Sales], Q1 ) )/ (( [Store Sales], Q2 ) – ( [Store Sales], Q1 ))

This is probably not what is desired, since you would expect a difference calculation to typically be evaluated on the final value of the measure, not on the components.

To get the desired value in AS2K, the only real option is to change either the cube or the query solve order. Unfortunately, if you’re using a client which automatically generates MDX changing the query may not be feasible. And there may be other forces which dictate particular solve order of cube members. On more than one occasion this has left us with no good solution.

Analysis Services 2005

With SSAS 2005 the notion of “scope” was added to solve order. The solve order of the cube is in its own scope, and is evaluated before any of the calculation in the query. So running the same query above in SSAS 2005 produces the expected result:


Store Sales Ratio

Difference

0

Q2

0.6

Q1

0.6


For the occasions where you actually want to have evaluation interact with the cube solve order, you can specify “SCOPE_ISOLATION=CUBE” within the query members definition.

See http://msdn2.microsoft.com/en-us/library/ms144787.aspx for more details about scope isolation and when you would use it.

Aggregate() changes

A related change is related to the Aggregate() function. In AS2K if the Aggregate() function had a higher solve order than what it was evaluating it would throw an error. It did this because there is no generic way of determining how to aggregate over a calculated member. Aggregation is really something that applies to base measures.

The fact that Aggregate members were required to have lower solve order produced headaches in my environment, because some client tools will specify a higher solve order for a member which uses Aggregate(). To counteract this we would set cube members to have solve orders higher than what we would ever expect the client to choose, which was a hacky and unreliable alternative (and also produced some of the unexpected values mentioned earlier).

In SSAS2005, on the other hand, Aggregate() has been enhanced to always apply to the base components of a expression, regardless of solve order. This is exactly the sort of behavior we would expect, and greatly reduces the constraints around solve order assignment within the cube.

Monday, March 24, 2008

Collection of Bash Tips

I ran across a selection of bash tips at http://www.shell-fu.org/lister.php?top. Many of them are very specific but here are a few that seem to come up daily:

Using expansion to move a file aside without having to type the file name twice

> cp ReallyLongFileNameYouDontWantToTypeTwice{,.orig}


Running a second command with the same arguments as the previous command, use '!*' to repeat all arguments or '!:2' to use the second argument. '!$' uses the final argument.
> cd /home/user/foo
cd: /home/user/foo: No such file or directory
> mkdir !*
mkdir /home/user/foo


Don't search history by grepping
~/.bash_history, or repeatedly hitting the up arrow, instead use CTRL+r (or '/' in vi-mode) for search-as-you type. You can immediately run the command by pressing Enter.

Make a whole directory tree with one command
Use the -p option to mkdir and make all parent directories along with their children in a single command.
>mkdir -p tmp/a/b/c


Use history to SUDO last command
Forget that your running as underprivileged? No need to retype the command.
> rpm blah
Permission denied
> sudo !!


Bash fork bomb
Don't forget the bash fork bomb. DO NOT TRY THIS AT HOME... Posted here so that you don't see this in a forum or a mailing list and use it without knowing:
>:(){ :|:& };:


Explanation:
:()
defines a function called : (accepts no arguments)
{ :|:& };
This is the function: It calls the function itself and pipes the output to the same function ":" and puts the process in the background. (Recursive invocation) with ; it ends the function definition
:
Calls the function and creates havoc.

Use ALT+. to insert last parameter
In bash (or anything using libreadline, such as mysql) press ALT+. to insert the last used parameter from the previous line.
Ex:
> vim some/file.c
> svn commit


Selected Bash Keystrokes:
Ctrl-U - Cuts everything to the left
Ctrl-W - Cuts the word to the left
Ctrl-Y - Pastes what's in the buffer
Ctrl-A - Go to beginning of line
Ctrl-E - Go to end of line

Thursday, October 4, 2007

Software Branding

The other day I stumbled across a link to a great software branding keynote speech at OSCON by a Google developer named Steve Yegge (who incidentally writes a great blog, available at http://steve-yegge.blogspot.com/). In the keynote he discusses the importance of branding and how it effects consumers perception of the product. Check it out and realize that branding isn't just someone up in marketing.

http://blip.tv/file/319044/

Friday, April 6, 2007

UI Smackdown: GWT vs. Flex vs. WPF/E (vs. Applets)

I attended the SRT User interface smackdown last week, which was an open spaces event to discuss GWT, Flex, and Windows Presentation Foundatation. Having been involved in a project using GWT I was particularly interested in how GWT would compare to Flex and WPF/E, which both allow embedded full fledged rich applications in the browser. I found GWT a great framework for creating Ajax applications, but Ajax itself has intrinsic problems that can make it painful to create even moderately complicated rich internet applications.

My take away from the session can be represented by the following matrix comparing the strengths of each.












GWT gets a green for zero-footprint since it requires no additional install. Flex is nearly zero-footprint, since Flash is ubiquitous. Virtually no one has WPF/E, so it almost certainly involves a download.

Both Flex and WPF/E support local files storage. They both have a sandbox in which they can save and read files from the local harddrive. By default the amount of space allowed is small, but Flex apps can request for arbitrarily large amounts of space from the user. Even small amounts of space opens up many new opportunities for a RIA that are unavailable with Ajax.

"Workflow support" in this matrix means support for the development process from designers all the way through implementation. This sort of workflow with GWT is as primitive as it is with lots of web application development: the designers deliver static mockups which developers try to mimic as closely as possible. When, inevitably, they change their mind about appearance the cycle repeats. Microsoft has a long way to go, but they have been much more proactive about trying to improve this situation, producing tools to allow designers to create the actual templates that get used by development.

Flex (and I think WPF/E) default to use binary socket communication, as opposed to HTTP. If firewall rules prevent such communication it will automatically fall back to HTTP. The ability to use binary socket communication opens up the possibility of doing real-time messaging. The alternative in Ajax is to use a "comet" style approach where an HTTP connection is held open for some period of time, and if any messages come through during that time they are sent. Flex will do comet style communication if it cannot establish a binary socket.

"Text quality" refers to the quality of the text as displayed on the screen. The general consensus in the session was that if your application is primarily about reading large amounts of displayed text, straight HTML displayed in the browser is superior.

Update 12/10/2007
Java applets were not included in this post, in part because they were not part of the session I went to, but also because I don't consider them a serious alternative for RIA. Bruce Eckel has a very good post about their deficiencies for RIA:
A common response to the “applets are dead” statement is “No they’re not. I still use them.” Applets aren’t useless; people still create very impressive things with them. The Java Posse highlights one or more applets each week. The statement should instead read, “Applets are dead for Web RIAs.” The installation process for the JRE and for any particular applet is not reliable enough for anyone to depend on them for a general-purpose website.

For the complete post see http://www.artima.com/weblogs/viewpost.jsp?thread=193593