April 2009
Mon Tue Wed Thu Fri Sat Sun
« Mar   May »
 12345
6789101112
13141516171819
20212223242526
27282930  

Month April 2009

CBusPASS Meeting – May 14th

Two weeks from today, Brent Ozar will be speaking at CBusPASS. This time around Brent will be presenting on Using Cloud-Based BI to Interpret Perfmon & Profiler Results. LiveMeeting will be available. There won’t be a dial-in number, though. Why? Because the sound will travel through Brent’s microphone, into a series of tubes, and then it will fly out of your speakers at a very high velocity. That’s right, we have integrated LiveMeeting sound! When the time comes you just need to join the LiveMeeting and you should be good to go.

The meeting will be held, as per the usual, at Battelle For Kids, 1160 Dublin Road Suite 500, Columbus, Ohio 43215.

Note: Battelle For Kids has moved to a new suite in the same building.

Abstract

After learning how to use Perfmon and Profiler to gather performance statistics about your SQL Server, it still takes a lot of time to interpret those results and figure out what’s going on. Microsoft’s SQL Server Data Mining team has built a free cloud-based data mining tool for Excel that can help slice and dice mountains of data and help you make sense of it all.

Even if you’re not ready for BI in the cloud, you can use this same type of tool in combination with a local SQL Server Analysis Services instance. Wait! Don’t freak out – it’s much easier than you think, and you never have to leave the comforting environment of Excel. Even if this doesn’t sound like fun to you, you might want to learn about it because mid-level managers in your company might want to use this technique to analyze sales or customer data.

Attendees will learn how to install & configure data mining in Excel, how to analyze Perfmon data to break the server’s load into categories, and how to use BI to write a performance report about your SQL Server.

Live Meeting

May 14th, 2009 @ 6:30 PM EST.

Live Meeting Login

Audio Information

Computer Audio
To use computer audio, you need speakers and microphone, or a headset.

First Time Users:
To save time before the meeting, check your system to make sure it is ready to use Microsoft Office Live Meeting.

Troubleshooting
Unable to join the meeting? Follow these steps:

  1. Copy this address and paste it into your web browser:
    https://www.livemeeting.com/cc/usergroups/join
  2. Copy and paste the required information:
    Meeting ID: NM86HK
    Entry Code: 5\-b6|jkH
    Location: https://www.livemeeting.com/cc/usergroups

Solving Business Problems with SQL

Businesses have all kind of interesting rules for working with data. Sometimes these rules are incredibly easy to implement in the database. Sometimes these rules are incredibly to implement in the application layer. Sometimes, it’s difficult to construct these rules no matter where you are in the entire application stack.

I recently came across a situation that required a bit of head scratching before I got things working correctly. What made this incredibly interesting to me was the apparent simplicity of the business rules.

The stored procedure must return a set of users, given an administrator’s user id, that the administrator is able to edit. An administrator is able to edit a user if the following criteria are met:

  1. There is at least one client in common between the administrator and the user.
  2. A user’s set of clients must all be members of the admin’s set of clients.
  3. If conditions 1 & 2 are not met, the user is excluded from the set and is effectively invisible to the administrator.

Before getting started working on real data, I created a sample set of data that I can share here:

IF OBJECT_ID('tempdb..#users') IS NOT NULL
  DROP TABLE #users;
GO

CREATE TABLE #users
(
  UserId INT,
  ClientId INT
);
GO

-- Admin
INSERT INTO #users VALUES (1, 1);
INSERT INTO #users VALUES (1, 2);
INSERT INTO #users VALUES (1, 3);

-- User with two clients
INSERT INTO #users VALUES (10, 1);
INSERT INTO #users VALUES (10, 2);

-- Another user with two clients
INSERT INTO #users VALUES (11, 2);
INSERT INTO #users VALUES (11, 3);

-- User with same clients as admin
INSERT INTO #users VALUES (12, 1);
INSERT INTO #users VALUES (12, 2);
INSERT INTO #users VALUES (12, 3);

-- User with overlapping set of clients
INSERT INTO #users VALUES (20, 2);
INSERT INTO #users VALUES (20, 3);
INSERT INTO #users VALUES (20, 4);

-- User with no matching clients
INSERT INTO #users VALUES (21, 4);
INSERT INTO #users VALUES (21, 5);
INSERT INTO #users VALUES (21, 6);

So, let’s start with an initial query:

SELECT *
  FROM #users AS a
       INNER JOIN #users AS b
          ON a.ClientId = b.ClientId

This really doesn’t tell us much, but it does give us a list of all users and any users who share the same client.

By adding a predicate to make sure that the user from the ‘a’ table is our administrator, like so:

SELECT *
  FROM #users AS a
       INNER JOIN #users AS b
          ON a.ClientId = b.ClientId
 WHERE a.UserId = 1

we’ve effectively fulfilled the first requirement:

There is at least one client in common between the administrator and the user.

Unfortunately, that’s the easy part. Determining if the user’s set of clients are a subset of the administrator’s set of clients is a little bit trickier. This is, actually, where a full outer join becomes incredibly helpful.

We’re going to change the query around considerably in order to get the desired results:

;WITH cte AS (
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS row_num,
       a.UserId AS a_UserId,
       a.ClientId AS a_ClientId,
       b.UserId AS b_UserId,
       b.ClientId AS b_ClientId,
       COUNT(*) OVER (PARTITION BY a.UserId, b.UserId) AS admin_count,
       COUNT(*) OVER (PARTITION BY b.UserId) AS user_count
  FROM (SELECT UserId,
               ClientId
          FROM #users
         WHERE UserId = 1) AS a
       FULL OUTER JOIN (SELECT UserId,
                               ClientID
                          FROM #users) AS b ON a.ClientId = b.ClientId
)
SELECT c.*
  FROM cte AS c
 WHERE admin_count = user_count
   AND a_UserId  b_UserId
 ORDER BY b_UserId

So, what did we change? Well, rather than directly joining from #users to #users, we’re using two sub-selects and have changed from an inner join to a full outer join. Changing to a full outer join will, as everyone knows, give us all rows from both queries: even if the user has access to a client but the administrator does not, that user’s information will still be returned.

Second, we’ve changed the core query to only return the administrator, rather than joining on all rows where the Client Ids are the same. Why? Well, we don’t care if other users have access to the same set or subset of clients, we only care if the users and the administrator share a common set of clients.

What’s with all of the COUNT(*) OVER (…) nonsense? Well, by using COUNT(*) and PARTITION BY (as I talked about last week in Using Partitioning Functions to Find Duplicate Rows ) you can detect duplicate rows. What you can also do is determine the count of specific criteria by using the PARTITION BY clause to do some implicit grouping in your query.

The first partition by on both a.UserId and b.UserId provides the row count for the number of times the unique combination of administrator and user occur in the overall result set.

The second partition by function provides the row count of the number rows that contain the user id in the total result set.

If the administrator row count does not equal the user row count we know that there are more user rows than there are administrator rows.

Why did I include the ROW_NUMBER() in the query? When I’m writing these kinds of queries I will typically include the ROW_NUMBER() windowing function so I can apply different criteria in the OVER clause to help keep track of the query. This is especially important when you’re dealing with a query that contains a large number of surrogate keys.

Finally, I wrapped everything in a CTE. This makes it possible to actually apply the count comparisons that I mentioned above. It also makes it easier to perform any additional filtering on the column names that I might need in the future for additional business rules.

Related Reading

Links for the Week of 2009.04.24

SQL Server

Filtered Indexes: What You Need To Know Michelle Ufford dives into the wonders of filtered indexes and explains what they are, why you need them, and how you can go about using them. Makes me wish we were on SQL Server 2008 at work.

Use SQL 2008 Express as a Central Management Server Wish you had a central management server in the office to help you manage your mountain of SQL 2005 machines? This functionality is even available if you’re using an express edition. Check out the link for more info.

Development

Code Sample Taxonomy What is sample code? What is reference code? What’s the difference? Phil Haack goes into the details and examines why the .NET community is up in arms about an ASP.NET MVC sample app.

Ditching the Micro Optimization Fetish Premature optimization is the bane of developers and, more appropriately, project managers everywhere. Don’t do it. Just don’t.

Stuff & Things

Linked Live IDs I have multiple Live IDs. I hate logging out and logging back in. Now I don’t have to.

Seven Productive Things To Do When You’re Bored At Work Do you get bored at work? Of course you do. Rather than clicking refresh over and over and over again on Digg you could spend your time doing something productive!

Embrace the Mundane, Appreciate the Simple Mike Walsh makes some excellent points about dealing with simple, mundane tasks. It all boils down to enjoying what you do. Take the time to appreciate it. Seriously, the next time you have to do something that makes you want to drag your feet, approach it with an open mind and embrace it.

Periodic Table of Typefaces ’nuff said.

Populating U.S. Federal Holidays in a Calendar Table

The title of this blog is only half as thrilling as the SQL. I can assure you.

I have a calendar table at work that is based off of the calendar table that you can find on aspfaq.com in an article titled Why should I consider using an auxiliary calendar table?

The big problem is that the holidays in the script are not actually federal holidays. They’re just a set of holidays that seemed significant to the author at the time of writing. The Federal government actually has rules about how to calculate holidays as well as a great list of federal holidays.

One of the more interesting rules is that if a holiday falls on a Saturday, the holiday is observed on a Friday. If the holiday falls on Sunday, the holiday is observed on Monday. That means New Year’s Day sometimes happens last year.

The following query is pretty self-explanatory and basically uses a few look forwards and look backs to figure out when holidays end up falling on the weekend and it makes a second, observed, holiday on the closest weekday.

I have verified this from 1999 through 2020 just to make sure that my math was correct against all posted Federal Holidays.

I hope this saves somebody some time.

UPDATE dbo.Calendar
   SET IsHoliday = 0;

-- New Year's day
UPDATE Calendar
   SET IsHoliday = 1
 WHERE M = 1
   AND D = 1;

-- New Year's day observed
--  if NYD is a Saturday
UPDATE Calendar
   SET IsHoliday = 1
  FROM Calendar AS c1
 WHERE c1.M = 12
   AND c1.D = 31
   AND c1.DW = 6
   AND EXISTS (SELECT 1
                 FROM Calendar AS c2
                WHERE c2.M = 1
                  AND c2.D = 1
                  AND c2.[Date] > c1.[Date]
                  AND DW = 7);

-- if NYD is a Sunday
UPDATE Calendar
   SET IsHoliday = 1
  FROM Calendar AS c1
 WHERE c1.M = 1
   AND c1.D = 2
   AND c1.DW = 2
   AND EXISTS (SELECT 1
                 FROM Calendar AS c2
                WHERE c2.M = 1
                  AND c2.D = 1
                  AND c2.[Date] < c1.[Date]
                  AND c2.DW = 1);

-- Martin Luther King Day
UPDATE Calendar
   SET IsHoliday = 1
  FROM Calendar AS c1
 WHERE c1.M = 1
   AND c1.DW = 2
   AND (SELECT COUNT(*)
          FROM Calendar AS c2
         WHERE c2.M = 1
           AND c2.DW = 2
           AND c2.Y = c1.Y
           AND c2.[Date] < c1.[Date]) = 2;

-- Washington's Birthday
UPDATE Calendar
   SET IsHoliday = 1
  FROM Calendar AS c1
 WHERE c1.M = 2
   AND c1.DW = 2
   AND (SELECT COUNT(*)
          FROM Calendar AS c2
         WHERE c2.M = 2
           AND c2.DW = 2
           AND c2.Y = c1.Y
           AND c2.[Date] < c1.[Date]) = 2;

-- Memorial Day
UPDATE Calendar
   SET IsHoliday = 1
  FROM Calendar AS c1
 WHERE M = 5
   AND DW = 2
   AND NOT EXISTS (SELECT 1
                     FROM Calendar AS c2
                    WHERE M = 5 AND DW = 2
                      AND c2.Y = c1.Y
                      AND c2.[Date] > c1.[Date]);

-- Independence Day
UPDATE Calendar
   SET IsHoliday = 1
 WHERE M = 7
   AND D = 4;

-- Independence Day, observed
--  if Independence Day is a Saturday
UPDATE Calendar
   SET IsHoliday = 1
  FROM Calendar AS c1
 WHERE c1.M = 7
   AND c1.D = 3
   AND c1.DW = 6
   AND EXISTS (SELECT 1
                 FROM Calendar AS c2
                WHERE c2.M = 7
                  AND c2.D = 4
                  AND c2.DW = 7
                  AND c2.[Date] > c1.[Date]);

--  if Independence Day is a Sunday
UPDATE Calendar
   SET IsHoliday = 1
  FROM Calendar AS c1
 WHERE c1.M = 7
   AND c1.D = 5
   AND c1.DW = 2
   AND EXISTS (SELECT 1
                 FROM Calendar AS c2
                WHERE c2.M = 7
                  AND c2.D = 4
                  AND c2.DW = 1
                  AND c2.[Date] < c1.[Date]);

-- Labor Day
UPDATE Calendar
    SET IsHoliday = 1
   FROM Calendar AS c1
  WHERE M = 9
    AND DW = 2
    AND NOT EXISTS (SELECT 1
                      FROM Calendar AS c2
                     WHERE M = 9 AND DW = 2
                       AND c2.Y = c1.Y
                       AND c2.[Date] < c1.[Date]);

-- Columbus Day
UPDATE Calendar
   SET IsHoliday = 1
  FROM Calendar AS c1
 WHERE c1.M = 10
   AND c1.DW = 2
   AND (SELECT COUNT(*)
          FROM Calendar AS c2
         WHERE c2.M = 10
           AND c2.DW = 2
           AND c2.Y = c1.Y
           AND c1.[Date] > c2.[Date]) = 1

-- Veterans' Day
UPDATE Calendar
   SET IsHoliday = 1
 WHERE M = 11
   AND D = 11 

-- Veterans' Day, observed
--  when Veterans' Day is a Saturday
UPDATE Calendar
   SET IsHoliday = 1
  FROM Calendar AS c1
 WHERE c1.M = 11
   AND c1.D = 10
   AND c1.DW = 6
   AND EXISTS (SELECT 1
                 FROM Calendar AS c2
                WHERE c2.M = 11
                  AND c2.D = 11
                  AND c2.DW = 7
                  AND c2.[Date] > c1.[Date]);

--  when Veterans' Day is a Sunday
UPDATE Calendar
   SET IsHoliday = 1
  FROM Calendar AS c1
 WHERE c1.M = 11
   AND c1.D = 12
   AND c1.DW = 2
   AND EXISTS (SELECT 1
                 FROM Calendar AS c2
                WHERE c2.M = 11
                  AND c2.D = 11
                  AND c2.DW = 1
                  AND c2.[Date] < c1.[Date]);

-- Thanksgiving Day
UPDATE Calendar
   SET IsHoliday = 1
  FROM Calendar AS c1
 WHERE M = 11
   AND DW = 5
   AND (SELECT COUNT(*)
          FROM Calendar AS c2
         WHERE M = 11
           AND DW = 5
           AND c2.Y = c1.Y
           AND c2.[Date] < c1.[Date]) = 3;

-- Christmas Day
UPDATE Calendar
   SET IsHoliday = 1
 WHERE M = 12
   AND D = 25;

-- Christmas Day, observed
--  when Christmas Day is a Saturday
UPDATE Calendar
   SET IsHoliday = 1
  FROM Calendar AS c1
 WHERE c1.M = 12
   AND c1.D = 24
   AND c1.DW = 6
   AND EXISTS (SELECT 1
                 FROM Calendar AS c2
                WHERE c2.M = 12
                  AND c2.D = 25
                  AND c2.DW = 7
                  AND c2.[Date] > c1.[Date]);

--  when Christmas Day is a Sunday
UPDATE Calendar
   SET IsHoliday = 1
  FROM Calendar AS c1
 WHERE c1.M = 12
   AND c1.D = 26
   AND c1.DW = 2
   AND EXISTS (SELECT 1
                 FROM Calendar AS c2
                WHERE c2.M = 12
                  AND c2.D = 25
                  AND c2.DW = 1
                  AND c2.[Date] < c1.[Date]);

Using Partitioning Functions to Find Duplicate Rows

Did you know that you can use the OVER clause, in conjunction with PARTITION BY to find duplicate rows in the database?

Here’s a business case for you:

There is a table consisting of UserId, SiteId, and ClientId:

IF OBJECT_ID('window_test') IS NOT NULL
  DROP TABLE window_test;

CREATE TABLE window_test
(
  UserId INT,
  SiteId INT,
  ClientId INT
);

Over time, data has been inserted into this table both through an application and through SSMS:

INSERT INTO window_test
SELECT 1, 1, 1
UNION ALL
SELECT 1, 2, 2
UNION ALL
SELECT 2, 1, 1
UNION ALL
SELECT 3, 1, 1
UNION ALL
SELECT 1, 3, 1;

SELECT * FROM window_test;

Unfortunately, what happened here is that the second row for user 1 (1, 2, 2) should not have been entered. There’s a business rule in place that a user should only belong to one client. We know that this user exists, but how many more users exist?

Well, the first way to test for this that most people would immediately reach for is to use a distinct count:

SELECT UserId,
       COUNT(DISTINCT ClientId) AS user_count
  FROM window_test
 GROUP BY UserId;

And this works perfectly. But the point of this is to show you a different way to do things. You can also accomplish the same thing using OVER and PARTITION BY:

SELECT UserId,
       COUNT(*) OVER (PARTITION BY UserId) AS user_count
  FROM window_test
 GROUP BY UserId, ClientId;

Unfortunately, this gives two results for the same user with the same count! Well, the easy way around that is to use a GROUP BY in an outer query, like so:

SELECT *
  FROM (SELECT UserId,
               COUNT(*) OVER (PARTITION BY UserId) AS user_count
          FROM window_test
         GROUP BY UserId, ClientId) AS x
 GROUP BY UserId, user_count;

Yes, I know I shouldn’t use a SELECT * in a query. I’m just trying to illustrate a point. Do as I say, not as I do.

Admittedly, for this situation, using a distinct count makes much more sense and is far less convoluted. However, there are many other situations where it’s preferable (if not necessary) to write a query using COUNT(*) OVER (…) instead of using convoluted logic or subqueries to return a row count.

Converting Measurements with T-SQL

I frequently find myself having to perform calculations on the source data based on a range of user supplied values. Usually there will be some kind of target and destination parameter supplied. So, for example, the users will want to see total sales in terms of burgers sold or something like that. Here’s where it gets tricky. Let’s say I own two franchises – one that sells burgers and one that sells tacos. I don’t want to know what my taco stand profits look like in terms of burgers. I want to see that number in terms of tacos.

So, what’s the best way to go about this?

Well, in order to get started you’re going to need the fn_split function to split strings and you’ll need a numbers table to create fn_split.

Once you have created your numbers table and the fn_split function you’ll want to set up some data to get started.

IF OBJECT_ID('conversions') IS NOT NULL
  DROP TABLE conversions;

IF OBJECT_ID('measurements') IS NOT NULL
  DROP TABLE measurements;

CREATE TABLE conversions
(
  convert_from INT,
  convert_to INT,
  factor DECIMAL (5, 1)
);

CREATE TABLE measurements
(
  m_type INT,
  measurement DECIMAL(18, 5)
);

INSERT INTO conversions
SELECT 1, 1, 1
 UNION ALL
SELECT 1, 2, 0.5
 UNION ALL
SELECT 1, 3, 4
 UNION ALL
SELECT 2, 1, 2
 UNION ALL
SELECT 2, 2, 1
 UNION ALL
SELECT 2, 3, 9
 UNION ALL
SELECT 3, 1, 4;

INSERT INTO measurements
SELECT 1, 50.5
 UNION ALL
SELECT 1, 100
 UNION ALL
SELECT 2, 93
 UNION ALL
SELECT 2, 76
 UNION ALL
SELECT 3, 56;

If you take a look at the data, you’ll see that there are a lot of possible combinations out there even with just this limited data set:

SELECT *
  FROM measurements AS m
       INNER JOIN conversions AS c
          ON m.m_type = c.convert_from

What’s the best way to limit these results so we aren’t writing strange where clauses? JOINs, of course!

Let’s say that our user wants to see all measurements with a type of 1 converted to the measurement of type 2 and measurements of type 2 converted to type 3 (this doesn’t really make much sense, I know, but business rules don’t have to make sense). Here’s what our input might look like:

DECLARE @source AS NVARCHAR(50);
DECLARE @target AS NVARCHAR(50);

SET @source = '1,2';
SET @target = '2,3';

Rather annoyingly, the best way I’ve found part from using comma delimited tuples is to do positional processing of data. Fortunately, the fn_split function supplies a position number as one of the output columns which makes keeping track of this sort of thing infinitely easier.

So, in order to move forward here’s what we do:

  1. Load @source into a temporary table
  2. Load @target into a temporary table
  3. Join #sources to #targets to create a master conversion table
  4. Profit!
IF OBJECT_ID('tempdb..#sources') IS NOT NULL
  DROP TABLE #sources;

IF OBJECT_ID('tempdb..#targets') IS NOT NULL
  DROP TABLE #targets;

IF OBJECT_ID('tempdb..#convert') IS NOT NULL
  DROP TABLE #convert;

SELECT pos, element AS c_from
  INTO #sources
  FROM dbo.fn_split(@source, ',');

SELECT pos, element AS c_to
  INTO #targets
  FROM dbo.fn_split(@target, ',');

SELECT s.pos, s.c_from, t.c_to
  INTO #convert
  FROM #sources AS s
       INNER JOIN #targets AS t
          ON s.pos = t.pos

Woohoo, we’re almost there. But how do we profit from this? Well, we use that query we wrote right after we filled the sample tables with data and we JOIN on the #convert table:

SELECT m.measurement AS original_measurement,
       (m.measurement * c.factor) AS converted_measurement
  FROM measurements AS m
       INNER JOIN conversions AS c
          ON m.m_type = c.convert_from
       INNER JOIN #convert AS conv
          ON c.convert_from = conv.c_from
         AND c.convert_to = conv.c_to

Through the magic of joins we’ve managed to convert more than one type of thing to another type of thing without having to resort to UNIONs (the insert doesn’t really count).

You also can download the entire example source code in a single file, rather than copying and pasting like a fiend: converting-measurements.sql

My First Microsoft Connect Item

I finally feel like a real SQL Server professional! I’ve submitted my first Connect feedback to Microsoft for a new feature of SQL Server: BOL for mobile devices.

This is a dream I’ve had since I first got my grubby little paws on my iPhone. Every day since then I’ve dreamed of having a copy of SQL Server Books Online on my iPhone. It would be better than games and movies on my iPhone. Heck, this would be better than just about any app for the iPhone. I even mentioned it to every Microsoft employee I could find at the PASS Summit. Most of them looked at me like I was at least a little bit crazy.

Why am I up in arms about this?

Do you know how many SQL questions I field? I’m pretty sure that if you’re reading this blog you do know how many SQL questions I field because you probably field more questions than I do. I get a lot of these questions when I’m nowhere near a computer and I’m not about to try to use MSDN over the EDGE network on a tiny little screen, which makes it tough to answer them. Plus, I wouldn’t have to lug giant SQL books to the doctor’s office so I have reading material. Instead I could pull out my trusty mobile device and read all about SQL Server while I wait for far too long to be told I’m not sick.

If you like the idea of having access to BOL anywhere you are, please vote for this Microsoft Connect item. Frankly, you just vote for it because it’s the coolest thing since sliced bread.

Links for the Week of 2009.04.17

SQL Server

The DBA… their role, expectations and future? What should a DBA be doing on a daily basis? What does their job entail? Here’s one version of that idea.

Spying on Your SPIDs: It’s sp_who but Better Even more info on how my users are ruining my database? YES PLEASE!

Development

Using jQuery Grid With ASP.NET MVC jQuery: win. ASP.NET MVC: win. jQuery + ASP.NET: double win! Phil Haack walks through using custom jQuery controls in this quick tutorial on jQuery and ASP.NET MVC

5 Blogs ASP.NET MVC Developers Should Be Following Love it or hate it, ASP.NET MVC is here and it’s the way of future ASP.NET development. Justin Etheredge lists out 5 + 1 blogs you should follow to pick up on ASP.NET MVC.

Stuff & Things

FREE MAGIC WANDS!

Michael Ruhlman on Freeing Yourself from Recipes Free yourself from the tyranny of recipes by understanding ratios!

Meet the New App Dev SIG Marketing Coordinator

It’s time to meet the new PASS App Dev SIG Marketing Coordinator: me!

What exactly will I be doing? Well, according to Blythe I will be doing the following:

  • Work directly with Blythe at PASS HQ to determine marketing strategy of the Application Development SIG
  • Come up with creative ways to get meeting information and new content out to the community
  • Work with other SIG groups to share marketing resources
  • Form press gangs Recruit volunteers
  • Help drive overall direction of the App Dev SIG
  • Bring Blythe delicious pastries from around the globe

What this REALLY means is that I’ll be working with PASS and with you, the community, to find new ways to raise awareness of the Application Development SIG, attract quality speakers, recruit you into service via some type of “draft” system, and find out what us App Dev SIG folks can do to help you.

Join a SIG, save an out of work actor.

Join a SIG, save an out of work actor.

Are you going to see me standing around on street corners waving App Dev SIG signs? It’s possible, especially if I need to bring back pastries from exotic locations like Schenectady, NY or Hartford, CT. However, more importantly, it means what I’ve said previously: I’m going to listen to the community, take that into account, and then accept bribes.

Wait, that’s not right.

I’ll be working with Blythe and Todd to get the word out about the App Dev SIG, drive content creation, and market the bejesus out of this thing. Your bribes of bacon will not work on me, largely because I don’t eat meat.

SQL Quiz, Part the Fourth!

I was tagged by SQLBatman in SQL Quiz 4. The topic of this round is:

Who has been a great leader in your career and what made them a great leader?

Honestly, I’ve had a lot of great bosses in my career but have come across even more great leaders. Like SQLBatman, I think it’s more appropriate to talk about the traits that have made those people great leaders rather than the people themselves.

Do it because you love it

This is a trait that I have found to be almost universal among the people I’ve always considered to be great leaders. They don’t strive for the limelight, they’re not doing what they’re doing for glory and name recognition. Instead, they’re doing it because they love what they’re doing. That passion shines through in every thing that they do and it’s infectuous. These are the people that not only make you excited to come to work, but they’re the people you go to for help because they’re so enthusiastic about what they do. And in this, they lead by following their own example. They love what they do, they do it because it’s fun and they enjoy it. They spread their enthusiasm in everything that they do.

Zen Mind, Beginner’s Mind

Yes, I did just use the title of a well-known Zen text in a blog post about leadership. A great leader knows that they need to be flexible and open-minded. Whether that’s being open minded to new ideas, solving employee gripes, or just looking at a problem in a different way, good leaders are always striving to keep their mind open and look at things differently.

Always Ready to Improve

A great leader is always looking for ways to get better at what they do. Whether it’s writing software, leading a team, or improving their communication skills, leaders are willing to take criticism and work on improving themselves. In addition to being willing to improve, leaders are capable of self-introspection and are capable of taking criticism.

At the end of a project, our team leader took the entire team aside and we had the opportunity to go around the room and, constructively, list positive and negative traits of our team members. Initially I was terrified about this. Rick led by example in this case and started everything off on a great note and the positive attitude towards introspection, self-discovery, and improvement was phenomenal. I gained a lot both personally and professionally out of the experience.

I suppose I should now tag some other people:

Michelle Ufford
Rick Kierner
Tim Benninghoff

This site is protected with Urban Giraffe's plugin 'HTML Purified' and Edward Z. Yang's Powered by HTML Purifier. 214 items have been purified.