SQLU MDX Week: Writing Simple Queries

December 14, 2011


This post is the second in a series of topics on MDX for SQL University. In my first post, Location, Location, Location, I introduced the tuple as a way to retrieve data from a cube with very precise instructions about what you want. In this post, I’m going to show you how to do that by writing queries. One thing that you will have to promise me as you read this post is to forget what you know about SQL queries (presuming you have some knowledge in that area). It will mess you up. If you start with a clean slate, you will have an easier time of it.

Preparing the Query Environment

Before I dive into writing queries, let me explain the setup. I’m using SQL Server 2008 R2 Analysis Services for these examples. You can work with earlier versions, but in some cases you will encounter date ranges that are four years earlier than the date shown in my examples. For example, instead of using Q3 2007, you would need to use Q3 2004. The measure values will remain the same. Here are links to the samples that you need to have installed:

Requesting a Tuple from a Cube

Okay, let’s start simple. Very, very simple. Go to SQL Server Management Studio, connect to Analysis Services, and click the MDX button on the query toolbar. An MDX query editor window will open. In the Available Databases drop-down list, select the Adventure Works database for your version of SSAS.

To retrieve a tuple from the cube named Adventure Works, you write a query like this:

SELECT FROM [Adventure Works] 
WHERE
([Product].[Product].&[359],[Date].[Date].[January 1, 2008],[Measures].[Sales Amount])

Notice the way that I refer to dimension members here. I’m no longer writing a pseudo-tuple as I did in my previous post, but am now using member unique names which tells Analysis Services the dimension and  hierarchy to which the member belongs. If you leave out the dimension and hierarchy, you will still get an answer, but no guarantee that you have the right answer if it’s possible that another dimension and hierarchy contain a member of the same name. For example, what if I have a West region and a sales person with the last name of West? Analysis Services will use one or the other to construct the tuple. The only way I can control which one is to use the dimension and hierarchy name. In fact, I switched from using Mountain-200 Black, 38 to [Product].[Product].&[359] because there are two products with the name Mountain-200 Black, 38 (due to Slowly Changing Dimensions) and I want the one that actually has sales for January 1, 2008. I can refer to members not only by name, but by the value in the key column – which in this case is the surrogate key for the dimension. I use an ampersand before the key value wrapped in brackets to specify that it’s a key column in the tuple rather than a member name .

Now let’s see the results of the query. Press F5 or the Execute button in the toolbar to see a single value appear in the Results pane.


The WHERE clause in your query contains the tuple that you want to retrieve. It does NOT behave like a WHERE clause in a SQL query, which is why I asked you nicely to forget about that other language – at least for the duration of this post. The problem with requesting a tuple this way is that the result does not include any metadata that tells me what I’m looking at. So I can enhance this query by showing one of the members of the tuple as a column label and one of the other members of the tuple as a row label, like this:

SELECT 
[Date].[Date].[January 1, 2008] ON COLUMNS,
[Product].[Product].&[359] ON ROWS
FROM [Adventure Works] 
WHERE [Measures].[Sales Amount]

Press F5 to see that the result of the query is the same, but now we have some more context for the value that displays.

The way that I like to think about the query results for this example is that it works in three phases. First, Analysis Services retrieves my request for the member on columns. Second, it retrieves my request for the member on rows. Those two steps occur completely independently of one another. Third, Analysis Services looks at the intersections produced by placing member on columns and rows and adds in the WHERE clause to produce a tuple. That’s why we get the same value in the result. It doesn’t matter which member you put on columns and which member you put on rows and which you leave in the WHERE clause. Collectively, they produce a tuple.

You don’t have to use a WHERE clause in the query. Instead, you could put everything onto an axis – either rows or columns. Essentially, you’re moving the tuple fragments out of the WHERE clause onto an axis. The tuple produced by the query parser is the same, but we get more metadata in the results to see the context of the query. For example, try this:

SELECT 
([Date].[Date].[January 1, 2008], [Measures].[Sales Amount]) ON COLUMNS,
[Product].[Product].&[359] ON ROWS
FROM [Adventure Works]

Here you see the results of the new query.

You can put any member of the tuple on either rows or columns. You can even write the query to show rows first and columns second like this:

SELECT 
[Product].[Product].&[359] ON COLUMNS,
([Date].[Date].[January 1, 2008], [Measures].[Sales Amount]) on ROWS
FROM [Adventure Works]

But the result of your query stays the same. You can have a query that only has a tuple fragment on columns like this:

SELECT 
([Date].[Date].[January 1, 2008], [Measures].[Sales Amount]) ON COLUMNS
FROM [Adventure Works]

But you cannot have a query that has a tuple fragment on rows like this:

SELECT 
([Date].[Date].[January 1, 2008], [Measures].[Sales Amount]) ON ROWS
FROM [Adventure Works]

If I don’t ask for something in a tuple explicitly by putting it on columns, on rows, or in the WHERE clause, Analysis Services plugs in the All member for the dimension and hierarchy that I didn’t include. Usually. There is an exception but we’ll save that explanation for another post. This behavior is especially helpful when you have lots of dimensions and hierarchies. Otherwise, you’d have a tuple that is  ginormous (your new technical term for the day).

Using Sets in a Query

Asking for data one tuple at a time is rather tedious. Fortunately, we can take our knowledge about query construction to the next level. Technically speaking, when we put a member on columns or rows, we were asking for a set. A set of one. When we put the tuple fragment on columns or rows, we were creating a tuple set. Another option is to explicitly create a set like this:

SELECT
{[Date].[Date].[January 1, 2008], [Date].[Date].[February 1, 2008]} ON COLUMNS,
[Product].[Product].&[359] ON ROWS
FROM [Adventure Works]
WHERE [Measures].[Sales Amount]

Whereas we use parentheses to denote a tuple, we use braces to denote a set. The order in which we define the member of the set determines the order in which the members display in the results. Try changing the sequence of members in the set to see the results.

MDX provides us with lots of functions to produce sets or to produce members that we use in sets so that we don’t have to list out members explicitly in a query. In my next post, we’ll explore some some of these functions.

1

SQLU MDX Week: Location, Location, Location

December 13, 2011


Once again, I am serving as the professor at SQL University during MDX week. MDX stands for MultiDimension eXpression language and we use it to add business logic to cubes in the form of calculations, named sets, and KPIs as well as to configure security and to write reports. I can’t teach you everything you need to know about MDX in just a few blog posts this week, but I can help you get into the right frame of mind to learn MDX, to get some insight into how the language works, and where to learn more to further your studies.

Before you undertake MDX, you should know something about Analysis Services and cubes. Earlier this year, I presented a series of posts as part of SQL  University to introduce you to this topic:

Before we dive into using MDX later this week, let’s start with perhaps the most fundamental concept that you need to understand – location, location, location.

Build On What You Know

You’ve probably used an Excel spreadsheet at some point and are familiar with using cell references to create formulas. For example, in the spreadsheet below, if I want to perform a calculation that includes the sales for the product “Mountain-200 Black, 38” on 1/1/2008, I would use the formula =B2. The letter B stands for the column reference and the number 2 stands for the row reference. It’s a two-dimensional cell reference.

“OK,” you’re thinking. “I got that. Rudimentary Excel. What does that have to do with MDX?” Bear with me a little bit longer and I’ll connect the dots for you.

Now consider that I have two sheets in a workbook with a similar layout. One sheet for 2008 sales and one sheet for 2007 sales. I want to calculate total sales for the same product in January. In this case, I can use the formula =’Sales 2008’!B2 + ‘Sales 2007’!B2. I’ve added a third dimension, the sheet name, to the cell references to tell Excel where to find the data for the calculation.

Let’s continue expanding on this concept:

  • For four dimensions, let’s assume that I have a separate workbook for different stores and I want to combine the sales for all stores for the same product and same month across the two years. My formula would now look like this – ‘[Store A.xlsx]Sales 2008’!B2 + ‘[Store B.xlsx]Sales 2008’!B2 + ‘[Store A.xlsx]Sales 2007’!B2 + ‘[Store B.xlsx]Sales 2007’!B2.
  • For five dimensions, I might use different folders on the same drive to store workbooks by promotion. So now each workbook reference would look something like this: ‘[C:\Top Customer Promotion\Store A.xlsx]Sales 2008’!B2.
  • Moving on to six dimensions, I can reference workbooks on different drives.
  • For seven dimensions, I can reference workbooks on different servers.

Now I’m going to get a bit silly, but just use your imagination with me for a moment because I can’t really do this. It’s just expanding the concept of location. Here goes… I can reference workbooks on different servers on different floors (eight dimensions), in different buildings (nine dimensions), on different streets (ten dimensions), in different cities (eleven dimensions), in different states (twelve dimensions), in different countries (thirteen dimensions), on different planets (fourteen dimensions) in different universes (fifteen dimensions)!

Okay, I’ve probably gone a bit too far with this example, and technically speaking, I wouldn’t make each of these aspects of a location into a separate dimension from an Analysis Services point of view. But I want you to get the idea that I can use location references in my Excel formulas to be very precise about which data to include in the formula. Excel understands relative references and absolute references. If you don’t tell it otherwise, it’s going to assume that you want a relative reference. That is, use the current cell, column, sheet,  or whatever that happens to be “current” for the cell in which you are typing the formula unless you give it explicit instructions to use a different cell, columns, sheet, or whatever.

And Now for the Tuple

Now let’s bring this back to MDX. A key concept in MDX is the tuple. I say tuh-ple because I learned it that way and I’m too old to change. (Think quintuple, sextuple, octuple – et cetera. The letter u is short the way that I learned.) Some people say too-ple, and that’s okay too. The beauty of reading a blog post is that you can read it with whichever pronunciation you prefer and my pronunciation won’t get in your way!

Let’s move our sales data from Excel into an Analysis Services cube. I’ve simplified the product name because the tire size in there seems to distract people. So “Mountain-200 Black, 38” becomes “Mountain-200 Black.”

To get data from a cube, I need to ask for that data in the form of a tuple. A tuple consists of one member from every dimension. So in my two dimensional representation of cube data above, the tuple to get sales for the Mountain-200 Black product in January would be (Mountain-200 Black, 1/1/2008).

Actually, that’s what I call a pseudo-tuple because it’s not exactly the way we would write it in MDX, but I don’t want you to get distracted by the details. For now, let’s focus on the concepts of a tuple.

Tuples are like coordinates that you learned in geometry. If you have a graph with two dimensions, x and y, you represent a point by using the coordinate (x,y). In geometry, order matters – the x must come before the y. But with tuples, order does NOT matter. We can write your example above as either (Mountain-200 Black, 1/1/2008) or (1/1/2008, Mountain-200 Black) and get the same answer: $66,095.71.

Now in our cube, most dimensions have an All level. And that counts as a cell, too. So we can create a tuple (All Products, All Dates) to get the grand total sales: $4,831,250.71.

If we have two kinds of measures in our sales, Sales Amount and Order Quantity, then that adds a third dimension to our cube. So our tuple changes accordingly to include the new dimension: (Mountain-200 Black, 1/1/2008, Sales Amount).

In summary, a tuple is just a location in a cube. We use it to tell Analysis Services where to find the data that we want. Using MDX functions, we can describe sets of tuples that we want to access “as is” or use in formulas. In my next post, I’ll explain how to write simple MDX queries using this concept of tuples.

2

Button, Button, Who’s Got the Button?

December 8, 2011

Yes, I’ve been quiet lately. I have a ton of ideas lining up for blog posts, but I need to get back to a “normal” pace. After conference season (PASS and Connections), I have been super busy with various projects – like co-authoring Introducing SQL Server 2012 with Ross Mistry and teaching classes like BI Immersion this week. One might say I’m having too much fun! Is that possible?

Background

Today’s post was inspired by a problem I encountered on the first day of the BI Immersion class. To make things easier for folks to have a working environment in which to try out the topics we discuss during the BI Immersion class, I recommend they get a freely available VHD with the entire Microsoft BI stack installed and configured. It’s evaluation software so it only works for a limited time, but it should be enough time for learning until you get your own permanent environment set up. Also, it’s not quite the entire BI stack, but we fix that during class by adding PowerPivot for SharePoint and adding another Reporting Services instance in SharePoint integrated mode. (Side note: Adding PowerPivot for SharePoint to an existing farm can be challenging – may need to do some fiddling to get it working.)

The Problem

As I was demonstrating Reporting Services (native mode) using the aforementioned VHD, I noticed that the Data Feed button was missing from the HTML Viewer toolbar. Yet, it was there in the toolbar when using Reporting Services in SharePoint integrated mode. You use this button to export data to PowerPivot for Excel – or any application that can consume an ATOM data feed. Where did the button go?

The Solution

My guess is that this VHD was not created from scratch using SQL Server 2008 R2, but rather migrated from an earlier version and somehow the RSReportServer.config file didn’t update properly. When I looked at the file for clues about the data feed button, I noticed that a rendering extension was missing. I added it back in as shown below (see the highlighted text), then opened up Report Manager to look at a report. Hooray – the button is back!

(Sorry about the lack of wrapping – I’ll fix it later. Have to get to class!)

<Render>
<Extension Name="XML" Type="Microsoft.ReportingServices.Rendering.DataRenderer.XmlDataReport,Microsoft.ReportingServices.DataRendering"/>
<Extension Name="NULL" Type="Microsoft.ReportingServices.Rendering.NullRenderer.NullReport,Microsoft.ReportingServices.NullRendering" Visible="False"/>
<Extension Name="CSV" Type="Microsoft.ReportingServices.Rendering.DataRenderer.CsvReport,Microsoft.ReportingServices.DataRendering"/>
<Extension Name="PDF" Type="Microsoft.ReportingServices.Rendering.ImageRenderer.PDFRenderer,Microsoft.ReportingServices.ImageRendering"/>
<Extension Name="RGDI" Type="Microsoft.ReportingServices.Rendering.ImageRenderer.RGDIRenderer,Microsoft.ReportingServices.ImageRendering" Visible="False"/>
<Extension Name="HTML4.0" Type="Microsoft.ReportingServices.Rendering.HtmlRenderer.Html40RenderingExtension,Microsoft.ReportingServices.HtmlRendering" Visible="False"/>
<Extension Name="MHTML" Type="Microsoft.ReportingServices.Rendering.HtmlRenderer.MHtmlRenderingExtension,Microsoft.ReportingServices.HtmlRendering"/>
<Extension Name="EXCEL" Type="Microsoft.ReportingServices.Rendering.ExcelRenderer.ExcelRenderer,Microsoft.ReportingServices.ExcelRendering"/>
<Extension Name="RPL" Type="Microsoft.ReportingServices.Rendering.RPLRendering.RPLRenderer,Microsoft.ReportingServices.RPLRendering" Visible="False" LogAllExecutionRequests="False"/>
<Extension Name="IMAGE" Type="Microsoft.ReportingServices.Rendering.ImageRenderer.ImageRenderer,Microsoft.ReportingServices.ImageRendering"/>
<Extension Name="WORD" Type="Microsoft.ReportingServices.Rendering.WordRenderer.WordDocumentRenderer,Microsoft.ReportingServices.WordRendering"/>
<Extension Name="ATOM" Type="Microsoft.ReportingServices.Rendering.DataRenderer.AtomDataReport,Microsoft.ReportingServices.DataRendering" Visible="false"/>
</Render>
0

Book Review: MDX with Microsoft SQL Server 2008 R2 Analysis Services Cookbook

October 21, 2011

1308EN_MDX with Microsoft SQL Server Analysis Services 2008 R2 Cookbook

As I mentioned in an earlier post, I first met Tomislav Piasevoli’s (blog|twitter) in 2008 at the PASS Summit in Seattle, and saw him again most recently again in Seattle at PASS Summit 2011. There I had the pleasure of telling him personally how much I liked his book. There are not many MDX books available, so when a new one arrives on the market, I definitely want to take a look. Now I have taught MDX classes for many years, and I think perhaps my first class was in 2002. However, it’s been so long now, I don’t recall exactly when that first class was. What I do know is that my understanding of MDX and my fluency with the language has grown by leaps and bounds since then through experience with all kinds of bleeding edge MDX, and I have tried to communicate some of my insights developed along the way to students in my classroom. MDX concepts can stretch your thinking (to put it mildly), and more so if you have to unlearn SQL concepts as well, which is true of the majority of my students. As a native English speaker, I can find it challenging at times to explain certain aspects of MDX. For all these reasons, I can fully appreciate Tomislav’s efforts to create this book and commend him for his excellent examples and explanations using a language that is not his mother tongue.

Tomislav’s book is definitely not for beginners. There is an underlying assumption that you already have some familiarity with the basics of MDX. The purpose of this book is to provide you with the tools necessary to continue building your skills. The chapters group together a series of related concepts, called recipes. You don’t need to read the book sequentially from cover to cover. Instead, you search for the desired outcome, such as handling division by zero errors (described in Chapter 1) or calculating row numbers (found in Chapter 7). Ideally, you don’t just read the recipe, but actually try out the steps yourself. I did some of my reading of this book when I was away from my laptop, and frequently found that I wanted to try out something that Tomislav mentioned. Even long-time MDX developers like myself can find interesting tidbits of information to round out their repertoire!

Each concept within a chapter is presented in a similar manner, beginning with “Getting ready” which are the steps you need to perform to set up your query. For example, you might need to work in Management Studio and set up a query as a starting point or open the Script View for a cube in Business Intelligence Development Studio. Then the next section is “How to do it…” which provides step-by-step instructions for working with a query or MDX script to accomplish the intended outcome. Then Tomislav continues with the “How it works…” section which provides background information on the key concepts for the current recipe. This section is the real meat of the book, but is nicely separated from the implementation steps if you want to jump straight to the technical details. Depending on the recipe, Tomislav also includes additional sections, such as “There’s more…” to provide alternative solutions or to point you to helpful links on the Internet such as whitepapers and blog articles providing more insight, and “See also…” to cross-reference you to another recipe in the book that covers a closely related concept.  Where applicable, he also includes information about how the techniques in the recipe behave differently in earlier versions of Analysis Services.

Chapter 1: Elementary MDX Techniques

Don’t let the word Elementary fool you into thinking you can learn entry-level MDX from this chapter. As I mentioned earlier, this book is not for beginners. There are good techniques here and a few basics, such as a great explanation of the FORMAT_STRING property and troubleshooting its use. However, I would consider the majority of these techniques to be elementary only as compared to the other techniques found later in the book. For example, the WHERE clause is one of those things that I see people really get into a tangle over (because they can’t forget their T-SQL), and Tomislav demonstrates using it to implement a logical OR on members from different hierarchies and a logical AND for members from the same hierarchy. One of my favorite sections in this chapter is the coverage of alternatives for the FILTER() function, which can cause performance problems. Use this chapter to get grounded with some foundational concepts, then strap on your seatbelt before diving into the rest of the book!

Chapter 2: Working with Time

Time is something that every cube has. Or at least every cube that I’ve ever met. I can’t imagine a cube without one (even if it’s called Date) because often business analysis is comparing one period to another or monitoring trends over time. Tomislav starts with the basics of the YTD() function but delves into variations on the theme and points out pitfalls to avoid. He moves on to parallel periods, moving averages, and finding last dates with data, among other time-related topics. A useful recipe in this chapter is the use of string functions to calculate a date, as I see this requirement a lot when working with Reporting Services reports that use Analysis Services as a source. A good case for working with a single-member named set rather than a calculated member is also made in this chapter.

Chapter 3: Concise Reporting

A report in this chapter means a pivot table used in some front-end tool for Analysis Services, and not Reporting Services exclusively. The goal of this chapter is to reduce the size of the pivot table, and thereby improve performance. I would characterize this chapter as one that helps you find the best or the worst members in a group, whether in a hierarchy, among siblings, or among descendants. Tomislav starts off the chapter with a recipe to get the top N members. In this recipe, Tomislav includes a great explanation of what can go wrong when you use the TopCount() function. Well, it’s not a matter of it behaving incorrectly because it’s doing what you ask. The problem is that many people misunderstand how the TopCount() function behaves under certain conditions and Tomislav delves deeply into the behavior here. He then builds on these ideas throughout the chapter and introduces alternatives for finding and displaying the best and the worst.

Chapter 4: Navigation

Hierarchies in a dimension are extremely useful for a number of reasons, one of which is navigation. The chapter begins with some simple queries that use Boolean logic to test the context of a current member on the row axis, and then expands to use scoping in the MDX script or use a query (using CELL CALCULATION) to determine if members are in the same branch of a hierarchy. Are you confused about when to use the Exists() function and the EXISTING keyword? Tomislav covers them both in this chapter in a variety of contexts. Also, having advocated on behalf of a named set in a previous chapter, Tomislav explores the pros and cons of named sets more fully in this chapter.

Chapter 5: Business Analytics

This chapter covers several techniques that are encountered less frequently (depending on who you ask, I suppose) than those covered up to this point in the book. For example, the chapter begins with linear regression which I’ve never had to use in 10 years of writing MDX. But I said the same about the Correlation() function once upon a time and I now use it frequently in a current project, so my feeling is that you never know when you’ll need to use a seemingly obscure function. Because these analytical functions are used less commonly, the amount of information available through Books Online or elsewhere on the Internet is pretty slim. Therefore, having this chapter’s working examples at your fingertips is invaluable. Also covered in this chapter is adjusting forecasts based on periodic cycles, alternative approaches to expense allocations, finding slow-moving inventory items, categorizing customers, and ABC analysis (which is an application of Pareto analysis).

Chapter 6: When MDX is Not Enough

In this chapter, Tomislav makes the case that when an MDX approach gets overly complicated, it’s time to look at making changes to the dimension or cube design. For example, he says, “Every time you catch yourself using functions like Except(), Filter(), or similar() too often in your calculations, you should step back and consider whether that’s a repeating behavior and whether it would pay off to have an attribute to separate the data you’ve been separating using MDX calculations.” He also explains how and why to create a placeholder measure in the cube to use with assignments in the MDX script. Utility dimensions for unit conversion or for time-based calculations are also covered in this chapter.

Chapter 7: Context-aware Calculations

Understanding context is an important aspect of MDX development. As Tomislav explains in the introduction to this chapter, context can be unpredictable based on what a user might select to place on rows and columns, or it can be partially known when you expect a particular measure or hierarchy to be used, or it can be completely known. The trick is to produce a calculation that behaves correctly regardless of context, which can be made trickier based on a combination of factors that Tomislav describes. The recipes in this chapter help you explore context from a number of, um, contexts, starting with how to know how many columns and rows will be in a query’s result set, how to determine which axis contains measures, how to determine what has been placed on an axis, among other useful techniques.

Chapter 8: Advanced MDX Topics

Now frankly I considered several of the recipes up to this point to be advanced, so I had to chuckle at the title of this chapter. Let’s just say these recipes are more complex! In this chapter, you’ll find techniques for working with parent-child hierarchies and displaying random values for sampling purposes. Hopefully, you’re avoiding the use of parent-child hierarchies and random sampling is not a common request in reports, so this section of the chapter is interesting primarily from an academic viewpoint. But then we move to complex sorts – a very useful subject indeed. Tomislav provides several examples and highlights potential problem areas. Also in this chapter is a recipe for recursively calculating cumulative values.

Chapter 9: On the Edge

Tomislav uses this chapter to collect topics that don’t neatly fit into the earlier chapters. Here he covers Analysis Services stored procedures (which are nothing like T-SQL stored procedures, by the way), as well as using the OPENQUERY() and OPENROWSET() functions for calling MDX from a T-SQL statement. He also introduces Dynamic Management Views (DMVs) for documenting and monitoring cubes, and shows how to use SQL Server Profiler to capture MDX queries. Last, he shows how to use the DRILLTHROUGH command.

If you’re an MDX developer, whether brand new or experienced, you will find lots of good information in this book and practical examples of how and why to implement specific techniques. I definitely recommend that you add it to your library, in whatever format you prefer. It’s available in paperback, PDF, ePub and Mobi from the publisher and in Kindle format from Amazon.

1

SQL Community, Twitter, and Hashtags

October 20, 2011
Tags:

I’ve been working with the Microsoft SQL Server BI stack since late 2000. When I started with SQL Server, my “community” consisted of my co-workers, my clients, and me. As communities go, it was a great community to be in. In 2001, our small boutique consulting company EssPro, founded by Mike Luckevitch, merged with another small boutique consulting company called Aspirity to create…Aspirity (which we lovingly referred to for a while as Aspirity 2 internally). Aspirity was the company who wrote the Microsoft Official Curriculum for the SQL Server 2000 BI stack – the DTS, OLAP, and MDX courses. I learned a lot about these products from the likes of Hilary Feier, Liz Vitt, Reed Jacobson, and Tom Chester. I even learned enough that they let me teach those courses, and thus my career as a BI trainer was launched. Eventually, they even let me write new courses and help co-author a book with Mike and Liz, Business Intelligence: Making Better Decisions Faster, thus launching my career as an author. Now that’s a great community!

But as great as that community was, it was only a microcosm of all the people working day in and day out with the Microsoft BI stack. I met many of them over the years at various Microsoft events, including my first PASS Summit in 2002. But in the early years of the past decade, I was one of many in an organization (even if it was small) that couldn’t send everyone to PASS, so it wasn’t until 2006 when I went independent that I could start going to PASS regularly. My community circle widened and PASS became a reunion for community. But even of all the people who were attending PASS, they still represented only a fraction of the community at large.

Somewhere along the line, Twitter became a phenomenon with the SQL Server community. When I first learned about Twitter, I didn’t understand the big deal. But now that I’ve been tweeting for a while, I’ve really come to appreciate the power of this medium for building relationships, sharing knowledge, and helping one another. I appreciate Twitter for its ability to create and foster community. And for a good laugh from time to time. So no matter where in the world that we find ourselves, our community is only a tweet away. We don’t need to meet face to face to be part of community. We simply need to engage.

One of the ways that the SQL Community engages to help one another by using Twitter is to use the #sqlhelp hashtag. (If you’re new to Twitter, a hashtag is a string of characters preceded by the # symbol and used to filter tweets so that you can easily find the tweets related to a particular topic.) But the SQL Server stack is loaded with a variety of technologies, and there’s a lot more traffic related to database engine Q & A than this business intelligence girl can sift through to spot where I can help.

Mark Vaillancourt (blog | twitter) – a thoroughly entertaining fellow that I met last week at PASS Summit 2011 – proposed the idea that the community should separate these Twitter traffic streams and introduced the #SSRSHelp hashtag earlier this week. Following along on that theme, I asked my fellow SSAS Maestro Council members if they would be willing to help me monitor a new hashtag, #SSASHelp, for questions related to Analysis Services and they agreed. Joining me are:

Of course, anyone can help us answer questions. Although the four of us are spread out across the US and Europe, covering a variety of time zones, we’re busy folks too (and occasionally sleep), so we can’t promise to be instantly available. The more people involved in helping, the more people we can help. And that’s what makes this community so awesome!

1