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 Potential Gotchas
  • 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

Potential Gotchas

Joining Strings

When building custom URLs for pages or images, it's common that people will try to use the default SQL string addition operator (+).  But the problem is that the default (+) operator will only work on strings.  If you pass [string] + [integer] you'll receive an error because any other data types will not be automatically converted.

An easy way we avoid this is to use the CONCAT function.  The concatenation function automatically converts all element types to strings before joining.  Instead of:

Generates an error

-- [NodeID] is an integer
'/Web/Url/Images/' + [NodeID] + '.gif' AS [Image]

use:

-- [NodeID] is an integer
CONCAT('/Web/Url/Images/', [NodeID], '.gif') AS [Image]

Converting Data Types

By design, the API will return the data type of the original element.  If you query for an element that's an integer, you will get an integer.  This makes perfect sense, until we start factoring in arithmetic.

Integers to Decimal

However, there are times when we want to change the data types.  One common example is doing averages of an element which is an integer.

Let's assume you have some historical response time numbers for a specific entity.

-- Fake query for discussion
SELECT Caption AS [Node Caption]       -- string
     , ResponseTime AS [Response Time] -- integer
FROM [Orion].[SomeRandomEntity]
WHERE [ObservationTimestamp] >= ADDMINUTE( -15, GETUTCDATE() )
  AND [Caption] = 'SERVER1'

 You would expect to get something like the below table.

Node Caption Response Times
SERVER1 1
SERVER1 4
SERVER1 5
SERVER1 7
SERVER1 11
SERVER1 45
SERVER1 15

The unit for response times is milliseconds, so they are stored as integers. 

-- Fake query for discussion
SELECT Caption AS [Node Caption]                    -- string
     , AVG(ResponseTime) AS [Average Response Time] -- ????
FROM [Orion].[SomeRandomEntity]
WHERE [ObservationTimestamp] >= ADDMINUTE( -15, GETUTCDATE() )
  AND [Caption] = 'SERVER1'
GROUP BY Caption

If you were to query for the average across this aggregate set, you would receive 12 as your result.  Doing some quick math, you'd see that the actual result should be closer to 12.57.  Why isn't the API capable of doing simple math?  It's doing it fine; it's just making some erroneous assumptions.

When you perform mathematical operations, the API looks to the "source" data type and expects the same in the result.  In simplest terms, it's seeing that you are querying across integers and therefore the result should be an integer.  It's a logical assumption that works 90% of the time but doesn't work when we start dividing or averaging those same integers.

There's an easy way to combat this problem.  Multiple the individual elements by 1.0.  The decimal point is critical here.

-- Fake query for discussion
SELECT Caption AS [Node Caption]                          -- string
     , AVG(1.0 * ResponseTime) AS [Average Response Time] -- force to a decimal
FROM [Orion].[SomeRandomEntity]
WHERE [ObservationTimestamp] >= ADDMINUTE( -15, GETUTCDATE() )
  AND [Caption] = 'SERVER1'
GROUP BY Caption

The API knows that an integer multiplied by a decimal number will result in a decimal number and takes this into account.  By telling the API that you want each integer multiplied by 1.0, the resultant data type will be a decimal value.

You must do the multiplication within the aggregate function and not upon the result.

Placement of the multiplication is important because we need to alter the types at the beginning of the call and not against the result of the arithmetic.

-- Fake query for discussion
SELECT Caption AS [Node Caption]                               -- string
     , AVG(1.0 * ResponseTime) AS [Average Response Time_Good] -- Do this
     , 1.0 * AVG(ResponseTime) AS [Average Response Time_Bad]  -- Not this
FROM [Orion].[SomeRandomEntity]
WHERE [ObservationTimestamp] >= ADDMINUTE( -15, GETUTCDATE() )
  AND [Caption] = 'SERVER1'
GROUP BY Caption

Strings to Decimals

if you have a data type that looks like a number, but is stored as a string, the same trick works.

SELECT TOP 1 '11' AS [This is a string]
     , 11 AS [This is an integer]
     , 11.0 AS [This is a decimal]
     , '11' * 1.0 AS [This is a decimal]
FROM Orion.RandomEntity

Why would numerical information ever be stored as a string? Although it's not best practice from a data organizational practice, there are several places where it's come up in the past.

Having this trick in your back pocket could prove useful.

  • SWQL Functions
  • SolarWinds Query Language (SWQL)
  • Gotchas
  • 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.