THWACK logo
THWACK
  • Sign In
  • Search
  • Community
    Community

    Find all you need to begin your THWACK journey, including documentation, missions, blogs, community groups, events, and media.

    Command Central
    • Getting Started
    MVP Program
    • MVP Program
    Monthly Mission
    • Hidden Gems
    Blogs
    • Community Announcements
    • Product Blog
    Groups
    • DevOps Discourse
    • Data Driven
    • See All Groups
    Events
    • SolarWinds User Group
    • THWACKcamp
      • ↪ 2024: On Demand
    • Bracket Battle
    Media Vault
    • Movies & Mainframes
    • TechPod
    • THWACK Tech Tips
    • THWACK Livecast
    • SolarWinds Lab Archive
    • THWACKcamp Archive
    • See All Media
  • Products
    Products

    Find the best place to learn and ask questions about your SolarWinds products.

    Observability
    • Observability Solutions
    • SolarWinds Observability SaaS
    • SolarWinds Observability Self-Hosted
    • SolarWinds Platform
    Network Management
    • Network Performance Monitoring
    • NetFlow Traffic Analyzer
    • Network Configuration Manager
    • IP Address Manager
    • User Device Tracker
    • VoIP & Network Quality Manager
    • Log Analyzer
    • Engineer's Toolset
    • Network Topology Mapper
    • Kiwi CatTools
    • Kiwi Syslog Server
    • ipMonitor
    Application Management
    • AppOptics
    • Loggly
    • Papertrail
    • Pingdom
    • DevOps
    IT Security
    • Access Rights Manager
    • Identity Monitor
    • Security Event Manager
    • Patch Manager
    • Serv-U FTP & MFT
    IT Service Management
    • SolarWinds Service Desk
    • Web Help Desk
    • DameWare Remote Support
    • DameWare Remote Everywhere
    • DameWare Mini Remote Control
    System Management
    • Server & Application Monitor
    • Virtualization Manager
    • Storage Resource Monitor
    • Server Configuration Monitor
    • SolarWinds Backup
    • Web Performance Monitor
    Database Management
    • Database Performance Analyzer
    • SQL Sentry
    • Database Performance Monitor
    • Database Mapper
    • Task Factory
  • Content Exchange
    Content Exchange

    Find downloadable files and templates other users have built and found useful to share with others.

    SolarWinds Platform
    • Alerts
    • Custom HTML
    • Custom Queries
    • Modern Dashboards
    • Reports
    • Scripts
    Server & Application Monitor
    • API Pollers
    • Application Monitor Templates
    Database Performance Analyzer
    • Custom Alerts
    • Custom Metrics
    • Custom Queries
    Server Configuration Monitor
    • Policies
    • Profiles
    Network Performance Monitor
    • Device Pollers
    • Universal Device Pollers
    Network Configuration Manager
    • Config Change Scripts
    • Device Templates
    • Firmware Upgrade Templates
    • Policy Documents
    SQL Sentry
    • Advisory Conditions
    Web Help Desk
    • Style Sheets
  • Resources
    SolarWinds Customer Portal Customer Portal

    Create individual user accounts for your team, manage your licenses, download your SolarWinds software, create and track support tickets, and more.

    SolarWinds Academy Academy

    A one-stop-shop for world-class training for SolarWinds products through on-demand videos, and instructor-led classes. All SolarWinds Academy content is included with every software purchase.

    SolarWinds Customer Success Support

    Get help when you need it from a world-class support team, available to assist with technical product issues 24 hours a day, seven days a week, 365 days a year.

    SolarWinds Partner Portal Partner Portal

    Accelerate SolarWinds Partners’ ability to drive digital and IT transformation for customers with powerful tools, resources, and increased profit potential.

  • Free Tools & Trials
  • Store
The SolarWinds Platform
  • Products
The SolarWinds Platform
SolarWinds Platform API Poor Man's PIVOT
  • Newsroom
  • Forums
  • SolarWinds Platform API
  • Content Exchange
  • What We're Working On
  • Feature Requests
  • More
  • Cancel
  • New
  • -SolarWinds Platform API
    • About the SolarWinds Information Service (SWIS)
    • +Setting up a Python Development Environment
    • +Using PowerShell 7+ and Visual Studio Code
    • +SolarWinds Query Language (SWQL) Basics
    • -Data Presentation Examples
      • Enhancing Custom Query Widgets
      • Poor Man's PIVOT
      • Potential Gotchas
      • Returning the Most Recent Element from a Related Entity
      • Working with Dates
    • Additional Resources
    • Glossary

Poor Man's PIVOT

Overview of PIVOT

For anyone who has worked with the SolarWinds Query Language (SWQL) for any amount of time knows that it mimics traditional SQL in many ways.  But there are some limitations that aren't put on traditional SQL.  Specifically, I'm looking at a few functions that don't exist in SWQL (at least of the time of this writing).  To say that SWQL and SQL are related it true; but they are second or third cousins, not siblings.

One such omission is the ability to pivot returned data.  If you are unfamiliar with the term, it's explained very well on Microsoft's site, but I've always thought of it like the "Paste as Transpose" that's in Excel.

Basically, it takes data that's like this:

Alpha Beta
Apple Banana
Alfalfa Bermuda
Astronaut Bakers

 and converts it to this:

Alpha Apple Alfalfa Astronaut
Beta Banana Bermuda Baker

Is this a gross over-simplification? You better believe it, but it's how my brain interprets this data.

Poor Man's SWQL PIVOT

Another limitation on SWQL is that it doesn't support all subqueries.  But there are ways to link tables together because SWQL does support JOINs.

I've written about why I dislike using JOINs in the past because SWQL has native functionality that renders most of them unnecessary.  If it's at all possible, you should leverage Navigation Properties.  They work better than JOINS for 90% of your queries.

To better illustrate how this works in practicality, we need two tables that are related by some type of common element.  Since this procedure works for (at least) SAM Script components that return multiple statistics and Universal Device Pollers, I'm going to propose two different entities (tables) for this discussion.

The Example Entities

Orion.EntityTable

SELECT ElementID
     , Caption
     , IPAddress
FROM Orion.EntityTable

ElementID Caption IPAddress
1111 WESCRUSHER 10.17.0.1
1112 Skywalker 192.168.199.11

Orion.EntityMultiLookupTable

SELECT ElementID
     , ElementName
     , ElementValue
FROM Orion.EntityMultiLookupTable

ElementID ElementName ElementValue
1111 AccountStat 1
1111 NumDrives 6
1111 HasDvdRom 0
1112 AccountStat 0
1112 NumDrives 2
1112 HasDvdRom 1

Our Desired Result Set

Caption IPAddress AccountStat NumDrives HasDvdRom
WESCRUSHER 10.17.0.1 1 6 0
Skywalker 192.168.199.11 0 2 1

Step-by-Step

  1. Build the initial query getting what you need from the first entity
     
    -- Step 1: Select what elements you can traditionally
    SELECT [ET].Caption
         , [ET].IPAddress
    FROM Orion.EntityTable AS [ET]
  2. Use a LEFT JOIN to connect that entity to the multiple element entity and add an additional filter for the element you want to retrieve
     
    -- Step 2: Adding the LEFT JOIN
    SELECT [ET].Caption
         , [ET].IPAddress
    FROM [Orion.EntityTable] AS [ET]
    LEFT JOIN [Orion.EntityMultiLookupTable] AS [EMLT]
      ON [ET].ElementID = [EMLT].ElementID
      AND [EMLT].ElementName = 'AccountStat'
  3. And add [EMLT].ElementValue AS [AccountStat] to your list of properties to return
     
    -- Step 3: Add your newly connected element
    SELECT [ET].Caption
         , [ET].IPAddress
         , [EMLT].ElementValue AS [AccountStat] <-- new
    FROM [Orion.EntityTable] AS [ET]
    LEFT JOIN [Orion.EntityMultiLookupTable] AS [EMLT]
      ON [ET].ElementID = [EMLT].ElementID
     AND [EMLT].ElementName = 'AccountStat'
  4. Since we want multiple elements from that target table, we just repeat with new aliases and element filters
     
    -- Step 4: Bring in additional information via joins and properties
    SELECT [ET].Caption
         , [ET].IPAddress
         , [EMLT].ElementValue AS [AccountStat]
         , [EMLT2].ElementValue AS [NumDrives]
         , [EMLT3].ElementValue AS [HasDvdRom]
    FROM [Orion.EntityTable] AS [ET]
    LEFT JOIN [Orion.EntityMultiLookupTable] AS [EMLT]
      ON [ET].ElementID = [EMLT].ElementID
     AND [EMLT].ElementName = 'AccountStat'
    LEFT JOIN [Orion.EntityMultiLookupTable] AS [EMLT2]
      ON [ET].ElementID = [EMLT2].ElementID
     AND [EMLT2].ElementName = 'NumDrives'
    LEFT JOIN [Orion.EntityMultiLookupTable] AS [EMLT3]
      ON [ET].ElementID = [EMLT3].ElementID
     AND [EMLT3].ElementName = 'HasDvdRom'
  5. Keep repeating step 4 until you have all the information in your result set you need.
  6. Use better names for the joined entity aliases - they can get numerous and hard to remember what's what
    -- Step 6: Think on it and use better names for your joined entities aliases
    SELECT [ET].Caption
         , [ET].IPAddress
         , [EMLT_AccountStat].ElementValue AS [AccountStat]
         , [EMLT_NumDrives].ElementValue AS [NumDrives]
         , [EMLT_HasDvdRom].ElementValue AS [HasDvdRom]
    FROM [Orion.EntityTable] AS [ET]
    LEFT JOIN [Orion.EntityMultiLookupTable] AS [EMLT_AccountStat]
      ON [ET].ElementID = [EMLT_AccountStat].ElementID
     AND [EMLT_AccountStat].ElementName = 'AccountStat'
    LEFT JOIN [Orion.EntityMultiLookupTable] AS [EMLT_NumDrives]
      ON [ET].ElementID = [EMLT_NumDrives].ElementID
     AND [EMLT_NumDrives].ElementName = 'NumDrives'
    LEFT JOIN [Orion.EntityMultiLookupTable] AS [EMLT_HasDvdRom]
      ON [ET].ElementID = [EMLT_HasDvdRom].ElementID
     AND [EMLT_HasDvdRom].ElementName = 'HasDvdRom'

Summary

In summation, the lack of the PIVOT function in the SolarWinds Query Language can be an annoyance then you're trying to represent data in a way that's appealing for you and for the consumers of your Observability solutions.  However, it's rarely needed because SWQL has Navigation Properties to help you do most of the heavy lifting.

Related Content

  • SWQL Pivot Example | THWACK Content Exchange - Custom Queries - The Orion Platform
  • Pivot
  • SolarWinds Query Language (SWQL)
  • Share
  • History
  • More
  • Cancel
Related
Recommended

SolarWinds solutions are rooted in our deep connection to our user base in the THWACK® online community. More than 200,000 members are here to solve problems, share technology and best practices, and directly contribute to our product development process.

SolarWinds Customer Success Center Certification SolarWinds Lab Link Customer Portal
About THWACK SolarWinds Blog Federal & Government Edit Settings Free Tools & Trials
Legal Documents Terms of Use Privacy California Privacy Rights Security Information
©2021 SolarWinds Worldwide, LLC. All Rights Reserved.