Speaking at Data Platform WIT/DEI Mental Health and Wellness Day 2023

On Friday, May 5th, 2023, I will be speaking at the Data Platform WIT/DEI Mental Health and Wellness Day. This is a free, virtual, all-day event for anyone working in technology. Topics range from dealing with stress, burnout, depression or chronic pain, to working in tech as a queer or neurodiverse person.

I will be presenting a session called Stressed, Depressed, or Burned Out? The Warning Signs You Shouldn’t Ignore. This is a deeply personal session based on my own experiences from the past decade, and it’s one of the few sessions I can’t and don’t want to rehearse. It won’t be an hour of incoherent rambling (don’t worry! πŸ˜‰) but it will be fairly raw and unfiltered.

Speaker card showing Cathrine Wilhelmsen presenting at Data Platform WIT/DEI Mental Health and Wellness Day 2023.

You can find the schedule and full agenda on the Data Platform Women in Tech website.

Solving FizzBuzz using SQL

Script icon.

This week, my coworkers and I were given a fun challenge. Using any tool or language, solve FizzBuzz! πŸ€“ Then present and explain the solution to the rest of the team. This was a fun challenge because our team is a mix of junior-to-senior developers and data professionals, working with everything from SQL to Python to C# to DAX to PowerShell. Those who had never solved FizzBuzz before got the chance to do so, while those who had already solved it got the chance to try again using a different tool or language.

While working on my solution, I ended up searching my own website for a post I wrote years ago: Using a Numbers Table in SQL Server. It gave me a nudge to share my FizzBuzz process and solution as well, even if there are a bazillion solutions already out there. I keep telling others to share what they do and learn, so this time I’m actually going to take my own advice. Go me! πŸ˜„

The FizzBuzz Challenge

FizzBuzz might be one of the most common programming challenges. The goal is to list all numbers from 1-100, but if a number is divisible by 3 you replace it with Fizz, if a number is divisible by 5 you replace it with Buzz, and if a number is divisible by both 3 and 5 you replace it with FizzBuzz:

  1. 1
  2. 2
  3. Fizz
  4. 4
  5. Buzz
  6. Fizz
  7. 7
  8. 8
  9. Fizz
  10. Buzz

…and so on.

Solving FizzBuzz in SQL

My first idea was to simply insert all values into a table and do a SELECT *, but I also wanted to actually solve the challenge πŸ˜‚

Step 1: List all numbers from 1-100

I came up with three approaches using ROW_NUMBER() to list all numbers from 1-100.

My first approach was to query sys.all_objects:

SELECT TOP (100)
  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n
FROM sys.all_objects
ORDER BY n;

This felt a little too quick and dirty, though.

Next, I wanted to see if I could list the numbers without querying a table/view. At this point, I had the idea of a numbers table (or tally table) in my mind, since I have used and blogged about it in the past. I just couldn’t remember the syntax! πŸ˜… So I boiled my logic down to “let’s just create 10 x 10 rows”. By using VALUES, I created two virtual tables with 10 rows (each containing the value 1), then cross joined the two tables:

SELECT
  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n
FROM (
  VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)
) AS t1(n)
CROSS JOIN (
  VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)
) AS t2(n)
ORDER BY n;

Finally, I looked up my numbers table syntax:

WITH
  L0   AS (SELECT 1 AS n UNION ALL SELECT 1),              -- 2 rows
  L1   AS (SELECT 1 AS n FROM L0 AS a CROSS JOIN L0 AS b), -- 4 rows (2 x 2)
  L2   AS (SELECT 1 AS n FROM L1 AS a CROSS JOIN L1 AS b), -- 16 rows (4 x 4)
  L3   AS (SELECT 1 AS n FROM L2 AS a CROSS JOIN L2 AS b), -- 256 rows (16 x 16)
  L4   AS (SELECT 1 AS n FROM L3 AS a CROSS JOIN L3 AS b), -- 65 536 rows (256 x 256)
  L5   AS (SELECT 1 AS n FROM L4 AS a CROSS JOIN L4 AS b), -- 4 294 967 296 rows (65 536 x 65 536)
  Nums AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n FROM L5)
SELECT TOP (100) 
  n 
FROM Nums 
ORDER BY n;

Step 2: Replace numbers with Fizz, Buzz, or FizzBuzz

Once I had figured out how to list the numbers, I needed to replace the numbers with Fizz, Buzz, and FizzBuzz. The challenge here, in any programming language, is to understand how to check whether a number is divisible by another number, and to understand in which order things are evaluated.

In SQL, you can use the % (modulus) operator to return the remainder after dividing one number by another. If the result is 0, it means that it is divisible.

(Fun fact: The first time I encountered the modulus operator, I thought that it returned the digit(s) after the decimal symbol. As in, I thought that 10 % 4 would return 5 because 10 / 4 = 2.5. Imagine my surprise when it returned 2! Why 2? And then I realized that ohhh, it’s because you can only fully fit the number 4 two times inside 10, and then you have 2 remaining… What can I say, math is difficult enough in my first language! πŸ˜…)

The final step is to construct the CASE expression so that it evaluates FizzBuzz first:

WITH
  L0   AS (SELECT 1 AS n UNION ALL SELECT 1),
  L1   AS (SELECT 1 AS n FROM L0 AS a CROSS JOIN L0 AS b),
  L2   AS (SELECT 1 AS n FROM L1 AS a CROSS JOIN L1 AS b),
  L3   AS (SELECT 1 AS n FROM L2 AS a CROSS JOIN L2 AS b),
  L4   AS (SELECT 1 AS n FROM L3 AS a CROSS JOIN L3 AS b),
  L5   AS (SELECT 1 AS n FROM L4 AS a CROSS JOIN L4 AS b),
  Nums AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n FROM L5)
SELECT TOP (100)
  CASE
    WHEN n % 3 = 0 AND n % 5 = 0 THEN 'FizzBuzz'
    WHEN n % 3 = 0 THEN 'Fizz'
    WHEN n % 5 = 0 THEN 'Buzz'
    ELSE CAST(n AS VARCHAR(3))
  END
FROM Nums
ORDER BY n;

Or, if you really just want that quick and dirty solution… 😁

SELECT TOP (100)
  CASE
    WHEN n % 15 = 0 THEN 'FizzBuzz'
    WHEN n % 3 = 0 THEN 'Fizz'
    WHEN n % 5 = 0 THEN 'Buzz'
    ELSE CAST(n AS VARCHAR(3))
  END
FROM (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n FROM sys.all_objects) AS t;

Your Turn!

How would you solve the FizzBuzz challenge? Can you think of a completely different approach? Can you fix my code and make it better or prettier? Go on, do it, it’s fun! πŸ˜ƒ

First Day as a Solutions Architect in Evidi!

Nope, I did not get a new job πŸ˜„ But! My company has officially merged with four other awesome companies into one super awesome company, and I got a promotion! I’m happy to announce that I’m now a Solutions Architect in Evidi, yay πŸ₯³

Cathrine Wilhelmsen sitting at her desk wearing an Evidi lanyard.

New Employer: Evidi

We used to be Skill, AITC, Communicate, eSeven, and Pilaro. Today, we are finally Evidi, one of Norway’s largest independent consulting companies with over 300 people specialized on Microsoft technologies. Our name comes from evidence and reflects the importance of data-driven decisions.

…seriously, it couldn’t have been more perfect for me. I’m already proud to say I work in Evidi, and I can’t wait to roll up my sleeves and do my part to help make Evidi the go-to partner for all things Microsoft in Norway πŸ€“

I’ll keep it short here, but if you want to learn more, check out these Norwegian articles:

And of course, our fancy new website: evidi.com 😁

New Role: Solutions Architect

If the new company announcement wasn’t enough… I ALSO GOT A PROMOTION! πŸ₯³

Ok, so, this wasn’t a surprise. I started working as a Senior Consultant with a goal of getting promoted to a Solutions Architect within a year. And I did it! It was important to me to have a goal to work towards, to get the opportunity to prove my worth, and to show that I do in fact have the skills and experience necessary to call myself a Solutions Architect.

I did it, I’m proud of myself, and I look forward to new goals and challenges, yay 😊

Microsoft Data Platform MVP 2022-2023: Swag Edition

Cathrine Wilhelmsen wearing an MVP hoodie, sitting by her keyboard with an MVP coffee mug. July 1st is an important day for all Microsoft MVPs: It’s the day we find out whether or not we have been re-awarded. This year, however, we had to wait until July 5th because of technical maintenance. Gulp! 😨 That meant a few more days of nervous hoping, waiting, and nail-biting…

When we finally got to July 5th, my Twitter timeline and LinkedIn feed exploded with happy announcements, yay! I’m so happy and thankful to receive my 8th MVP Award this year and become a Microsoft Data Platform MVP 2022-2023! πŸ€“πŸ₯³

This award means even more to me because I’ve had a rough couple of years. Many of us have been struggling, and I think most of us have had our lives changed in some way during the pandemic. For many, the pandemic meant new opportunities. Those who were previously unable to travel to events could suddenly participate in all kinds of virtual events, which was amazing! Others turned around and used the opportunity to start blogging or creating video content or podcasts. I have seen so many existing and new MVPs emerge and shine these past couple of years, which makes me so so so happy 🀩

At the same time, I felt completely lost. I was not able to turn around and try new things. I tried, I failed, I let people down, and I had to prioritize handling several personal issues over contributing to the community. In many ways, I let myself down. At the same time, I know I did the right thing taking care of myself first, and I know I did as much as I was able to. I had accepted that if that wasn’t enough to be re-awarded, it would be ok. But it was enough, and I’m so grateful to be recognized by Microsoft again πŸ₯°

Receiving another MVP Award gave me such a boost of inspiration and motivation to continue being involved in this amazing community. Receiving some cool swag made it all even better. (I can now properly cosplay as a hacker, woohoo! πŸ‘©πŸΌβ€πŸ’») I will totally be smiling proudly whenever I wear this hoodie πŸ€“

Ingest and Explore LEGO Datasets using Pipelines and Serverless SQL in Azure Synapse Analytics

Woman standing next to a projector showing the Azure Synapse Analytics logo.

In the April session of the Azure Synapse Analytics and Microsoft MVP series, I got to show one of my favorite demos: ingesting and exploring LEGO datasets! πŸ€“ In just a few minutes, I grab a compressed file from the web, decompress it, store it as a Parquet file in my data lake, and run SQL queries on it using Serverless SQL. It really is that simple:

If you want to try this demo yourself, you can follow the detailed steps below. Have fun! πŸ˜ƒ