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.
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
run: flights -> { group_by: carrier # percent aggregate: percent_of_flights is flight_count / all(flight_count) }
carrier | percent_of_flights |
---|---|
WN | 25.74% |
US | 10.93% |
AA | 10.03% |
NW | 9.74% |
UA | 9.5% |
DL | 9.32% |
RU | 4.66% |
MQ | 4.6% |
EV | 4.57% |
HP | 2.83% |
AS | 2.45% |
CO | 2.07% |
B6 | 1.4% |
OH | 1.28% |
TZ | 0.88% |
[ { "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 flights."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 flights 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%)
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 }
integer | dollars | neg_dollars |
---|---|---|
344827 | $344,827 | ($344,827) |
[ { "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 flights ORDER BY 1 desc NULLS LAST
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"
.
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 }
dep_date | longest_flight_time | total_flight_time | flight_count |
---|---|---|---|
2005-12-31 | 6 hours 2 minutes | 12 days 9 hours | 175 |
2005-12-30 | 7 hours 44 minutes | 14 days 14 hours | 188 |
2005-12-29 | 8 hours 5 minutes | 13 days 20 hours | 186 |
2005-12-28 | 7 hours 20 minutes | 14 days 3 hours | 197 |
2005-12-27 | 8 hours | 14 days 3 hours | 197 |
2005-12-26 | 8 hours | 13 days 16 hours | 194 |
2005-12-25 | 1 day 8 hours | 13 days 5 hours | 167 |
2005-12-24 | 8 hours 9 minutes | 11 days 21 hours | 159 |
2005-12-23 | 7 hours 47 minutes | 14 days 1 hour | 201 |
2005-12-22 | 7 hours 46 minutes | 13 days 10 hours | 200 |
2005-12-21 | 5 hours 21 minutes | 14 days 21 minutes | 192 |
2005-12-20 | 7 hours 29 minutes | 14 days 11 hours | 203 |
2005-12-19 | 5 hours 46 minutes | 12 days 20 hours | 207 |
2005-12-18 | 7 hours 44 minutes | 14 days 7 hours | 179 |
2005-12-17 | 5 hours 19 minutes | 11 days 2 hours | 139 |
2005-12-16 | 7 hours 35 minutes | 15 days 6 hours | 195 |
2005-12-15 | 6 hours 52 minutes | 14 days 8 hours | 204 |
2005-12-14 | 7 hours 35 minutes | 15 days 39 minutes | 193 |
2005-12-13 | 5 hours 26 minutes | 13 days 18 hours | 190 |
2005-12-12 | 7 hours 29 minutes | 13 days 18 hours | 176 |
[ { "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', flights."dep_time") as "dep_date", max(flights."flight_time") as "longest_flight_time", COALESCE(SUM(flights."flight_time"),0) as "total_flight_time", COUNT( 1) as "flight_count" FROM '../data/flights.parquet' as flights GROUP BY 1 ORDER BY 1 desc NULLS LAST LIMIT 20