Malloy Documentation
search

Malloy's render provides a variety of ways to render numeric values. Tagging a number will change how the number is displayed in the result set but the underlying value doesn't change.

The following examples that follow use the Malloy semantic data model below.

document
source: airports is duckdb.table('../data/airports.parquet') extend {
  dimension: name is concat(code, ' - ', full_name)
  measure: airport_count is count()
}

source: flights is duckdb.table('../data/flights.parquet') extend {
  join_one: orig is airports on origin = orig.code
  join_one: dest is airports on destination = dest.code

  measure: flight_count is count()
}

# percent

Carriers as percentage of flights

document
run: flights -> {
  group_by: carrier
  # percent
  aggregate: percent_of_flights is flight_count / all(flight_count)
}
QUERY RESULTS
[
  {
    "carrier": "WN",
    "percent_of_flights": 0.2573783375431738
  },
  {
    "carrier": "US",
    "percent_of_flights": 0.10928088577750582
  },
  {
    "carrier": "AA",
    "percent_of_flights": 0.10027347046489979
  },
  {
    "carrier": "NW",
    "percent_of_flights": 0.09738216554968143
  },
  {
    "carrier": "UA",
    "percent_of_flights": 0.09499546149228454
  },
  {
    "carrier": "DL",
    "percent_of_flights": 0.09317715840116929
  },
  {
    "carrier": "RU",
    "percent_of_flights": 0.046614679244954715
  },
  {
    "carrier": "MQ",
    "percent_of_flights": 0.046020178234302996
  },
  {
    "carrier": "EV",
    "percent_of_flights": 0.04573017774130216
  },
  {
    "carrier": "HP",
    "percent_of_flights": 0.028275048067581715
  },
  {
    "carrier": "AS",
    "percent_of_flights": 0.024513741673360845
  },
  {
    "carrier": "CO",
    "percent_of_flights": 0.020703135195329833
  },
  {
    "carrier": "B6",
    "percent_of_flights": 0.01404182387110058
  },
  {
    "carrier": "OH",
    "percent_of_flights": 0.012818021790637044
  },
  {
    "carrier": "TZ",
    "percent_of_flights": 0.00879571495271542
  }
]
WITH __stage0 AS (
  SELECT
    group_set,
    CASE WHEN group_set=1 THEN
      base."carrier"
      END as "carrier__1",
    (CASE WHEN group_set=1 THEN
      COUNT(1)
      END)*1.0/MAX((CASE WHEN group_set=0 THEN
      COUNT(1)
      END)) OVER () as "percent_of_flights__1"
  FROM '../data/flights.parquet' as base
  CROSS JOIN (SELECT UNNEST(GENERATE_SERIES(0,1,1)) as group_set  ) as group_set
  GROUP BY 1,2
)
SELECT
  "carrier__1" as "carrier",
  MAX(CASE WHEN group_set=1 THEN "percent_of_flights__1" END) as "percent_of_flights"
FROM __stage0
WHERE group_set NOT IN (0)
GROUP BY 1
ORDER BY 2 desc NULLS LAST

# number

Malloy uses LookML's (Excel) string definitions for formatting numbers.

# number="0"             # Integer (123)
# number="*00#"          # Integer zero-padded to 3 places (001)
# number="0 \" String\"" # Integer followed by a string (123 String)
                              #   Note \"String\" can be replaced with any other word

# number="0.##"          # Number up to 2 decimals (1. or 1.2 or 1.23)
# number="0.00"          # Number with exactly 2 decimals (1.23)
# number="*00#.00"       # Number zero-padded to 3 places and exactly 2 decimals (001.23)
# number="#,##0"         # Number with comma between thousands (1,234)
# number="#,##0.00"      # Number with comma between thousands and 2 decimals (1,234.00)
# number="0.000,,\" M\"" # Number in millions with 3 decimals (1.234 M)
                              #   Note division by 1 million happens automatically
# number="0.000,\" K\""  # Number in thousands with 3 decimals (1.234 K)
                              #   Note division by 1 thousand happens automatically

# number="$0"            # Dollars with 0 decimals ($123)
# number="$0.00"         # Dollars with 2 decimals ($123.00)
# number="\"€\"0"        # Euros with 0 decimals (€123)
# number="$#,##0.00"     # Dollars with comma btwn thousands and 2 decimals ($1,234.00)
# number="$#.00;($#.00)" # Dollars with 2 decimals, positive values displayed
                              #   normally, negative values wrapped in parenthesis

# number="0\%"           # Display as percent with 0 decimals (1 becomes 1%)
# number="0.00\%"        # Display as percent with 2 decimals (1 becomes 1.00%)
# number="0%"            # Convert to percent with 0 decimals (.01 becomes 1%)
# format="0.00%"         # Convert to percent with 2 decimals (.01 becomes 1.00%)
document
run: flights -> {
  // tag a single element
  aggregate:
    # number="0"
    `integer` is flight_count

  // tag multiple elements at once.
  # number="$#,##0;($#,##0)"
  aggregate:
    dollars is flight_count
    neg_dollars is 0 - flight_count
}
QUERY RESULTS
[
  {
    "integer": 344827,
    "dollars": 344827,
    "neg_dollars": -344827
  }
]
SELECT 
   (COUNT(1)) as "integer",
   (COUNT(1)) as "dollars",
   0-(COUNT(1)) as "neg_dollars"
FROM '../data/flights.parquet' as base

Durations

The # duration renderer interprets a value as a number of seconds and renders it as a human-adjusted duration. Other units can be specified like # duration="minutes", with possible units of "nanoseconds", "microseconds", "milliseconds", "seconds", "minutes", "hours", and "days".

document
run: flights -> {
  group_by: dep_date is dep_time.day
  # duration="minutes"
  aggregate: 
    longest_flight_time is max(flight_time)
    total_flight_time is flight_time.sum()
  aggregate:
    flight_count    
  limit: 20
}
QUERY RESULTS
[
  {
    "dep_date": "2005-12-31T00:00:00.000Z",
    "longest_flight_time": 362,
    "total_flight_time": 17874,
    "flight_count": 175
  },
  {
    "dep_date": "2005-12-30T00:00:00.000Z",
    "longest_flight_time": 464,
    "total_flight_time": 21054,
    "flight_count": 188
  },
  {
    "dep_date": "2005-12-29T00:00:00.000Z",
    "longest_flight_time": 485,
    "total_flight_time": 19923,
    "flight_count": 186
  },
  {
    "dep_date": "2005-12-28T00:00:00.000Z",
    "longest_flight_time": 440,
    "total_flight_time": 20367,
    "flight_count": 197
  },
  {
    "dep_date": "2005-12-27T00:00:00.000Z",
    "longest_flight_time": 480,
    "total_flight_time": 20381,
    "flight_count": 197
  },
  {
    "dep_date": "2005-12-26T00:00:00.000Z",
    "longest_flight_time": 480,
    "total_flight_time": 19683,
    "flight_count": 194
  },
  {
    "dep_date": "2005-12-25T00:00:00.000Z",
    "longest_flight_time": 1920,
    "total_flight_time": 19037,
    "flight_count": 167
  },
  {
    "dep_date": "2005-12-24T00:00:00.000Z",
    "longest_flight_time": 489,
    "total_flight_time": 17130,
    "flight_count": 159
  },
  {
    "dep_date": "2005-12-23T00:00:00.000Z",
    "longest_flight_time": 467,
    "total_flight_time": 20241,
    "flight_count": 201
  },
  {
    "dep_date": "2005-12-22T00:00:00.000Z",
    "longest_flight_time": 466,
    "total_flight_time": 19360,
    "flight_count": 200
  },
  {
    "dep_date": "2005-12-21T00:00:00.000Z",
    "longest_flight_time": 321,
    "total_flight_time": 20181,
    "flight_count": 192
  },
  {
    "dep_date": "2005-12-20T00:00:00.000Z",
    "longest_flight_time": 449,
    "total_flight_time": 20855,
    "flight_count": 203
  },
  {
    "dep_date": "2005-12-19T00:00:00.000Z",
    "longest_flight_time": 346,
    "total_flight_time": 18514,
    "flight_count": 207
  },
  {
    "dep_date": "2005-12-18T00:00:00.000Z",
    "longest_flight_time": 464,
    "total_flight_time": 20605,
    "flight_count": 179
  },
  {
    "dep_date": "2005-12-17T00:00:00.000Z",
    "longest_flight_time": 319,
    "total_flight_time": 15966,
    "flight_count": 139
  },
  {
    "dep_date": "2005-12-16T00:00:00.000Z",
    "longest_flight_time": 455,
    "total_flight_time": 22007,
    "flight_count": 195
  },
  {
    "dep_date": "2005-12-15T00:00:00.000Z",
    "longest_flight_time": 412,
    "total_flight_time": 20679,
    "flight_count": 204
  },
  {
    "dep_date": "2005-12-14T00:00:00.000Z",
    "longest_flight_time": 455,
    "total_flight_time": 21639,
    "flight_count": 193
  },
  {
    "dep_date": "2005-12-13T00:00:00.000Z",
    "longest_flight_time": 326,
    "total_flight_time": 19801,
    "flight_count": 190
  },
  {
    "dep_date": "2005-12-12T00:00:00.000Z",
    "longest_flight_time": 449,
    "total_flight_time": 19841,
    "flight_count": 176
  }
]
SELECT 
   DATE_TRUNC('day', base."dep_time") as "dep_date",
   max(base."flight_time") as "longest_flight_time",
   COALESCE(SUM(base."flight_time"),0) as "total_flight_time",
   COUNT(1) as "flight_count"
FROM '../data/flights.parquet' as base
GROUP BY 1
ORDER BY 1 desc NULLS LAST
LIMIT 20