This guide helps people who are familiar with building SQL queries or dbt models to understand the concepts of Honeydew.If you are familiar with semantic layers in BI or are not familiar with SQL, head over to the introduction instead.
Honeydew is a standalone semantic layer.It has many similarities to semantic layers that are embedded in BI tools such as Tableau, Looker or Power BI. However, unlike semantic layers embedded in a
particular BI tool, Honeydew can be used by any data tool or SQL client.Semantics include the following concepts:
How business entities (such as “customer”) are mapped to data sources (which tables to read from)
How data tables are related (which joins to use)
How metrics are calculated (which aggregations to perform)
Metadata (such as descriptions, display names, formatting) associated with presenting those objects to business users.
Those metrics are then used in by BI tools, reports, notebooks, and AI agents for data queries.Most SQL queries or dbt models for a specific use case would include (1) - (3): join and aggregate the data to a level a BI tool can use.BI tools with dashboard for that use case would include metadata (4), and some aggregation logic (3) - when aggregating data further for a specific plot or a widget.
For example, consider a Tableau report on sales activity:
Most commonly it would load data from a SQL view or a SQL table built for it with aggregated data relevant for the report:
daily sales metrics, broken down by many dimensions such as customer segments or geographies.
The Tableau workbooks on top of that table would present widgets like daily growth. Those widgets would aggregate data
from the table for the widget - i.e. sum the total sales metrics across all customer segments to present total growth.
The query that builds the sales activity data for the dashboard might share logic with queries that build
other reports like a sales pipeline report.
The core job of a semantic compiler such as Honeydew is to act as an
intermediate layer between data and user tools, separating the semantics into their own layer.Building a semantic layer follows the DRY principle: “do not repeat yourself”. Do not define multiple times how a customer table
is connected to a sales table, or how unique users are counted for different grains.
A VIEW or a dbt model built with SQL has a static structure: specific metrics, grouped by specific dimensions, with specific filters applied.A semantic layer on the other hand, is dynamic: every query can change filters or groupings of a metric.
For example, consider a unique user count metric built in SQL:
-- daily user countSELECT sales.order_date, COUNT(DISTINCT sales.customer_id) AS user_countFROM salesGROUP BY 1
This query prepares the user count on a daily level. However, if would need distinct user count per month this query would not suffice.
Instead, would need to create a different query:
-- monthly user countSELECT DATE_TRUNC(month, sales.order_date) as order_month, COUNT(DISTINCT sales.customer_id) AS user_countFROM salesGROUP BY 1
More complexity would create more queries:
-- a basic user activity report for TableauCREATE VIEW user_report AS-- user counts by geography and daySELECT customer.geography, sales.order_date, COUNT(DISTINCT sales.customer_id) AS user_countFROM salesJOIN customerON sales.customer_id = customer.customer_idGROUP BY customer.geography, sales.order_dateUNION ALL-- total user counts by day across all geographiesSELECT NULL as geography, sales.order_date, COUNT(DISTINCT sales.customer_id) AS user_countFROM salesGROUP BY sales.order_date
Set the relationship between sales and customer, connected on customer_id.
Create a user_countmetric defined as COUNT(DISTINCT sales.customer_id). Note the definition of a metric is a standalone function that can aggregate data.
Instead of operating on the user_report view, Tableau would now operate on a virtual table called world.
Honeydew presents itself to any user tool as a virtual “flat” table.
A widget showing users by day and geography will run
-- customer count by day and geographySELECT "customer.geography", "sales.order_date", SUM("sales.user_count")-- world is a virtual table from HoneydewFROM worldGROUP BY 1,2
It would actually run a query that joins sales and customer and builds the user_count aggregation accordingly.
Note that the query uses SUM as an aggregation. The user_count metric is actually a distinct count, but the tool that sends the SUM does not know that.That means that user_count is a virtual aggregation - Honeydew translates the SUM to the right implementation automatically.
Another widget that only wants monthly totals would call
-- customer count by day and geographySELECT DATE_TRUNC(month, "sales.order_date") as order_month, SUM("sales.user_count")-- world is a virtual table from HoneydewFROM worldGROUP BY 1
With a semantic layer, build the components of a view (the aggregations, the joins) instead of the view itself.That means that those components can be reused for infinite number of ad-hoc questions, instead of the specific one that a view query was built for.
A select statement in SQL creates a single query. In a semantic layer however you build the components of a SELECT (its joins, sources, calculations) separately, and then re-use them.
To create a specific SELECT query from components, use the Playground in Honeydew UI or a user entity in Honeydew must have like a SQL client connected to Honeydew.It is very common to build components (like the calculation of user count) and then test them (by day, by month, by geography) in the playground.
A granular table used in a SQL query corresponds to an Entity in Honeydew.Entities can be based on a table or a view in the data warehouse, or on a custom SQL query.
An entity in Honeydew must have a primary key defined.Users typically map into Honeydew only tables with a unique key, such as facts and dimensions.If there isn’t a primary or a unique key present in a table, must create a key as part of the data preparation.
SQL queries join multiple tables together.Joins in Honeydew are defined once as Relationships between entities.Relationships have similar properties to join such as:
Join fields: which fields connect the tables. Note there might be multiple fields (called a composite connection), or a calculation used for the join.
Honeydew allows to use multiple fields to join and/or build and use calculated attributes to join on calculations.
Honeydew does not support range joins, only equality joins.
Join Type: part of the relationship definition in Honeydew is the type of join - INNER, LEFT, RIGHT or FULL OUTER.
Unlike queries, once a join type is set in the semantic layer all joins will use the chosen join type.Customizing join type in a specific metric calculation is a planned future extension.
There are also properties that have no equivalence to a query JOIN condition.Those properties affect how the calculation is done after the JOIN is made:
Direction: whether its a one-to-many or a many-to-one join.
The direction of the join lets Honeydew know which rows will get duplicated after the join was done. Using that knowledge, Honeydew can
correctly account for duplicated rows when aggregating the data.
The cross filtering) of a join lets Honeydew know whether filters travel through that join.
Typically, in SQL, filters (WHERE) are performed after joins, so a field in one table can filter other tables.
However, in a semantic layer might want to control whether filters on table X affect table Y or not.One particular application is when joining facts and dimensions: should a filter on one dimension affect another
dimension when joined through the fact?The default is “both” which behaves like a SQL query where all filters affect all tables.
SELECT DATE_TRUNC(month, sales.sales_date) as sales_monthFROM sales
Those calculation create new columns within a query. The equivalent in a semantic layer is a
calculated attribute in a Honeydew entity.Calculated attributes as SQL snippets that create “virtual columns” in entities:
sales.sales_month_num = MONTH(sales.sales_date)
Those fields can be reused for other fields, for example:
sales.is_q4 = sales.sales_month_num BETWEEN 10 AND 12
Calculated attributes can include window functions. Those window functions treat their entity as the table:
sales.cumulative_customer_sales =SUM(sales.sales_amount) OVER (PARTITION BY sales.customer_id ORDER BY sales.order_date)
Window functions serve specific use cases that requires calculations between rows in the same entity, such as building sessions
or cumulative sums.Most aggregation use cases are served better by building metrics - see below.
Calculated attributes in Honeydew can operate over more than one table.For example, if there is a product entity that is related (directly or indirectly) to a sales entity, then can create:
Relationships and joins in Honeydew are automatically resolved.Every expression can assume that all entities are accessible to it, and Honeydew will join as needed.Expression that are impossible to compute (because there is no possible join to perform) would result in an error
SQL does not have the concept of a standalone aggregation function. Aggregations in SQL always operate in a specific context (of a GROUP BY or a WHERE)In a semantic layer like Honeydew a metric is a first-class citizen - a reusable custom aggregation function.A basic metric is built like this:
If a basic metric in Honeydew is an aggregation, a derived metric is one that is built from other metrics.For example, can create this set of metrics:
-- basic metricssales.total_cost = SUM(sales.quantity * product.unit_price)sales.total_amount = SUM(sales.sales_amount)-- a profit metric is composed from two other metricssales.profit = sales.total_amount - sales.total_cost
There is no limit on metric composition: stack and reuse metrics in any way
Metrics are sensitive to the user query context.That means that the computed result of a metric would depend on the query - the filters and groups in use.User context includes:
Filtering - filters that come from a user query
Grouping - groups that come from a user query
Metrics in Honeydew can change the user context for their calculation, applying additional filters or changing group by.
It’s easy to think of each metric calculated in a Honeydew generated query as its own CTE.By default, the CTE to calculate a metric would use the GROUP BY the user has asked for in the query, and would operate
on the data as it was filtered by the user.But what if want a particular metric to be calculated with a different GROUP BY? Or have another WHERE condition?That is changing the user context for the metric.
A common pattern in SQL is to use CASE WHEN to create a filtered aggregation:
sales.red_sales_amount =SUM(CASE WHEN product.color = 'Red' THEN sales.sales_amount ELSE 0 END)
A filtered aggregation adds a filter on top of the user context.Honeydew offers a different way called a filter qualifier to apply filters
to metrics that are already defined:
-- a basic metricsales.total_amount = SUM(sales.sales_amount)-- a derived filtered metricsales.red_sales_amount = sales.sales_amount FILTER (WHERE product.color = 'Red')
Filter qualifiers enable to create filtered metrics over any aggregation.
The default value for SUM and COUNT aggregations where there is no data available is automatically 0.Other aggregations will have NULL as the value for an empty dataset.Default values can also be controlled explicitly using the DEFAULT qualifier -
Filter qualifiers can also apply directly to aggregations:
-- a filtered metric on an aggregationsales.red_sales_amount =SUM(sales.sales_amount) FILTER (WHERE product.color = 'Red')
It’s always recommended to use FILTER (WHERE ...) rather than a CASE WHEN in an aggregation - as that allows Honeydew
to sometimes construct a more efficient query
A common pattern in SQL is using the same aggregation with different filters in order to build a combined metric, like a ratio.Consider the following SQL statement:
-- SQL query for sales of red products out of all product salesSELECT sales.order_date, DIV0( -- Aggregate over red rows SUM(CASE WHEN product.color = 'Red' THEN sales.sales_amount END), -- Aggregate over all rows SUM(sales.sales_amount) ) as red_sales_out_of_all_salesFROM salesLEFT JOIN productON sales.product_id = product.product_idGROUP BY order_date
The equivalent in Honeydew would be a derived metric:
-- a ratio metric for red salessales.red_sales_ratio =DIV0( sales.total_amount FILTER (WHERE product.color = 'Red'), sales.total_amount)
Can also use the sales.red_sales_amount defined above for the same result:
sales.red_sales_ratio =-- a ratio metric for red salesDIV0( sales.red_sales_amount, sales.total_amount)
DIV0 is usually preferred to a division operator as it can gracefully handle division by zero.
This derived metric perform two actions:
The numerator is aggregating the sales amount only on red product rows (note that happens after applying any user filters supplied in the query)
The denominator is aggregating the sales amount over all products
The actual aggregation (how sales.total_amount is calculated) is defined once, and reused in the derived metric twice.
Metrics in Honeydew can also change the user grouping context.Consider the following SQL statement that compares a total aggregation to an aggregation over a partial segment:
-- SQL query for product % contribution to total salesWITHtotal_sales AS ( SELECT SUM(sales.sales_amount) as total_sales FROM sales),product_sales AS ( SELECT product.product_id, SUM(sales.sales_amount) as product_sales FROM sales LEFT JOIN product ON sales.product_id = product.product_id GROUP BY product_id)SELECT product_id, DIV0(product_sales, total_sales) as product_contribution_to_totalFROM total_sales, product_sales
How would you build a similar metric in Honeydew?Let’s build a metric in Honeydew that is even more dynamic: the % contribution to total sales of any user group. It can contribution of a product, or it can be any other group.That metric would be:
-- Honeydew metricsales.contribution_to_total =DIV0( sales.total_amount, sales.total_amount GROUP BY ())
This derived metric perform two actions:
The numerator is grouped by the user’s grouping (can be by product or otherwise)
The denominator is grouped by nothing, removing any user groups
The GROUP BY (...) qualifier sets the grouping for a metric. It can be nothing (as in the example above),
or it can be specific:
-- Honeydew metricsales.contribution_to_yearly_sales =DIV0( sales.total_amount, sales.total_amount GROUP BY (date.year))
-- SQL query for average daily sales for each productWITHdaily_product_sales AS ( SELECT product.product_id, sales.order_date, SUM(sales.sales_amount) as daily_product_sales FROM sales LEFT JOIN product ON sales.product_id = product.product_id GROUP BY product_id, order_date)SELECT product_id, AVG(daily_product_sales) as daily_avg_product_salesFROM daily_product_sales
How would you build a similar metric in Honeydew?But one that is more dynamic: one that can adjust to any user groupThat metric would be:
-- Honeydew metricsales.avg_daily_sales = AVG( sales.total_sales GROUP BY (*, sales.order_date) )
This derived metric performs two actions:
The internal aggregation is grouped by the user’s grouping + date
The external aggregation is grouped by the user’s grouping only
If that metric is grouped by product, the result would be average daily product sales.If that metric is grouped by customer segment, the result would be average daily segment sales.If that metric is grouped by product and customer segment, the result would be average daily sales per product, per segment.
Metric in Honeydew can also be used as filters for further calculations, similar to how HAVING operates in SQL.Consider the following SQL statement:
-- SQL query for average sale amount, ignoring products with less than $100 in daily sales-- list products that had more than $100 in sales per dayWITH daily_active_products AS ( SELECT sales.order_date, sales.product_id, FROM sales GROUP BY ALL HAVING SUM(sales.sales_amount) > 100)-- average sale amount by state, only for products that had >$100 daily sales volumeSELECT location.state, AVG(sales.sales_amount) as avg_sales_of_active_productsFROM salesINNER JOIN daily_active_products ON sales.product_id = daily_active_products.product_id AND sales.order_date = daily_active_products.order_dateLEFT JOIN location ON sales.location_id = location.location_id
That calculates average sales of active products per state.The equivalent Honeydew metric would be dynamic to any user choice of a grouping, allowing to slice average sales of active products by location or any
other user grouping choice.That expression would be a filtered metric based on a metric:
sales.avg_sales_of_active_products =-- Honeydew metric for average sale amount for active productsAVG(sales.sales_amount)FILTER (WHERE sales.total_amount GROUP BY (sales.order_date, sales.product_id) > 100)
The sales.total_amount metric is used in the filter with a specific grouping (daily products) and a filter (over $100 in sales)
The external aggregation is an AVG that operates on any data that passed the internal filter.
If the metric above is used in a query that groups by location.state then it would return it grouped by state.It can also be used with any other grouping!
CTEs in SQL are commonly used to create aggregated data as part of a larger calculation, for example:
-- sales per customerWITH customer_sales AS ( SELECT customer_id, SUM(sales.sales_amount) as customer_sales FROM sales JOIN customer ON sales.customer_id = sales.customer_id GROUP BY customer_id)-- average customer sales by customer type-- customer type - VIP for customers with >$1000 of total salesSELECT CASE WHEN cs.customer_sales > 1000 THEN "VIP" ELSE "NOT VIP" END AS customer_type AVG(cs.customer_sales) as avg_customer_salesFROM customerJOIN customer_salesON customer.customer_id = customer.customer_idGROUP BY 1
Calculated attributes in Honeydew can use metrics, which is a very common translation for CTEs.The equivalent for that expression would be a calculated attribute in customer:
-- calculated attribute in Honeydew customer entitycustomer.customer_sales = SUM(sales.sales_amount)
If a calculated attribute in entity uses an aggregation, then that aggregation is grouped to the
entity primary key (customer_id in the example above).
And a derived attribute
-- calculated attribute in Honeydew customer entitycustomer.customer_type = CASE customer.customer_sales > 1000 THEN "VIP" ELSE "NOT VIP" END
A better deconstruction for that CTE would build a metric for sales:
--- metric in Honeydew sales entitysales.total_sales = SUM(sales.sales_amount)
And reuse the metric in the customer entity
--- calculated attribute in Honeydew customer entitycustomer.customer_sales = sales.total_sales
That would behave the same way as using the aggregation.
Was this page helpful?
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Honeydew Documentation","colors":{"primary":"#abcb1a","light":"#CBE74A","dark":"#9cb918"},"logo":{"light":"https://mintcdn.com/honeydew/FY_ZgBcPUZJ2-No3/logo/logo.svg?fit=max\u0026auto=format\u0026n=FY_ZgBcPUZJ2-No3\u0026q=85\u0026s=10dbf238c7bdb5bb1ee94e85eea8049f","dark":"https://mintcdn.com/honeydew/FY_ZgBcPUZJ2-No3/logo/logo-white.svg?fit=max\u0026auto=format\u0026n=FY_ZgBcPUZJ2-No3\u0026q=85\u0026s=c774c9340ba4f0a8828b7ad8aa1e4179","href":"https://honeydew.ai"},"favicon":"https://mintcdn.com/honeydew/mXl3IrOWJ_NESw09/favicon.png?fit=max\u0026auto=format\u0026n=mXl3IrOWJ_NESw09\u0026q=85\u0026s=4b76e0217dbafaa5c1b88b130a5e62c4","navbar":{"links":[{"href":"https://app.honeydew.cloud/signup","label":"Sign Up"},{"href":"https://app.honeydew.cloud/","label":"Login"},{"href":"https://honeydew.ai","label":"Website"}],"primary":{"type":"button","label":"Book a Demo","href":"https://honeydew.ai/get-started/"}},"footer":{"socials":{"twitter":"https://twitter.com/honeydewai","linkedin":"https://www.linkedin.com/company/honeydewai","github":"https://github.com/honeydew-ai"}},"integrations":{"ga4":{"measurementId":"G-3FG56HVDQ6"},"gtm":{"tagId":"GTM-MNTHZF6"},"hotjar":{"hjid":"3749326","hjsv":"6"},"segment":{"key":"SPDgvdM9OoZSCirKWUQj58GrrjBEzOoE"}},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"honeydew","hasAudioNarration":false,"actualSubdomain":"honeydew","customDomains":["honeydew.ai"],"gitSource":{"type":"github","owner":"honeydew-ai","repo":"docs","deployBranch":"main","contentDirectory":"content","isPrivate":false,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6aeb09fbe84fb046db8b74d1","collectionId":"bd93d249-2ab8-4a00-9172-b288e5de6540","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6aeb09fbe84fb046db8b74d1"},"feedback":{"thumbs":true},"entitlements":{},"buildId":"6aeb09fbe84fb046db8b74d1","clientVersion":"0.0.4067","searchFilterCounts":[{"language":"default","tag":"Integrations","count":48},{"language":"default","tag":"Modeling Reference","count":30},{"language":"default","tag":"BI Tools","count":19},{"language":"default","tag":"Management","count":17},{"language":"default","tag":"Security","count":11},{"language":"default","tag":"Recipes","count":10},{"language":"default","tag":"Advanced Modeling","count":8},{"language":"default","tag":"Authentication","count":7},{"language":"default","tag":"Governance","count":7},{"language":"default","tag":"Context Layer","count":7}]},"assistantConfig":{},"basePath":"/docs","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"migration/sql-guide","slug":"/migration/sql-guide","pageMetadata":{"title":"From SQL to Honeydew","description":null,"href":"/migration/sql-guide"},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,em:`em`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Note,Tip,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Note)_missingMdxReference(`Note`,true);if(!Tip)_missingMdxReference(`Tip`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(Tip,{children:[_jsx(_components.p,{children:`This guide helps people who are familiar with building SQL queries or dbt models to understand the concepts of Honeydew.`}),_jsxs(_components.p,{children:[`If you are familiar with semantic layers in BI or are not familiar with SQL, head over to the `,_jsx(_components.a,{href:`/introduction`,children:`introduction`}),` instead.`]})]}),`\n`,_jsx(Heading,{level:`2`,id:`introduction`,children:`Introduction`}),`\n`,_jsx(_components.p,{children:`Honeydew is a standalone semantic layer.`}),`\n`,_jsx(_components.p,{children:`It has many similarities to semantic layers that are embedded in BI tools such as Tableau, Looker or Power BI. However, unlike semantic layers embedded in a\nparticular BI tool, Honeydew can be used by any data tool or SQL client.`}),`\n`,_jsx(_components.p,{children:`Semantics include the following concepts:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsx(_components.li,{children:`How business entities (such as “customer”) are mapped to data sources (which tables to read from)`}),`\n`,_jsx(_components.li,{children:`How data tables are related (which joins to use)`}),`\n`,_jsx(_components.li,{children:`How metrics are calculated (which aggregations to perform)`}),`\n`,_jsx(_components.li,{children:`Metadata (such as descriptions, display names, formatting) associated with presenting those objects to business users.`}),`\n`]}),`\n`,_jsx(_components.p,{children:`Those metrics are then used in by BI tools, reports, notebooks, and AI agents for data queries.`}),`\n`,_jsx(_components.p,{children:`Most SQL queries or dbt models for a specific use case would include (1) - (3): join and aggregate the data to a level a BI tool can use.`}),`\n`,_jsx(_components.p,{children:`BI tools with dashboard for that use case would include metadata (4), and some aggregation logic (3) - when aggregating data further for a specific plot or a widget.`}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:`For example, consider a Tableau report on sales activity:`}),_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`Most commonly it would load data from a SQL view or a SQL table built for it with aggregated data relevant for the report:\ndaily sales metrics, broken down by many dimensions such as customer segments or geographies.`}),`\n`,_jsx(_components.li,{children:`The Tableau workbooks on top of that table would present widgets like daily growth. Those widgets would aggregate data\nfrom the table for the widget - i.e. sum the total sales metrics across all customer segments to present total growth.`}),`\n`]}),_jsx(_components.p,{children:`The query that builds the sales activity data for the dashboard might share logic with queries that build\nother reports like a sales pipeline report.`})]}),`\n`,_jsxs(_components.p,{children:[`The core job of a `,_jsx(_components.a,{href:`/semantic-compiler`,children:`semantic compiler`}),` such as Honeydew is to act as an\nintermediate layer between data and user tools, separating the semantics into their own layer.`]}),`\n`,_jsx(_components.p,{children:`Building a semantic layer follows the DRY principle: “do not repeat yourself”. Do not define multiple times how a customer table\nis connected to a sales table, or how unique users are counted for different grains.`}),`\n`,_jsx(Heading,{level:`2`,id:`views-vs-semantic-layer`,children:`VIEWs vs Semantic Layer`}),`\n`,_jsx(_components.p,{children:`A VIEW or a dbt model built with SQL has a static structure: specific metrics, grouped by specific dimensions, with specific filters applied.`}),`\n`,_jsx(_components.p,{children:`A semantic layer on the other hand, is dynamic: every query can change filters or groupings of a metric.`}),`\n`,_jsx(Heading,{level:`3`,id:`sql-queries-for-bi`,children:`SQL Queries for BI`}),`\n`,_jsx(_components.p,{children:`For example, consider a unique user count metric built in SQL:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`6`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- daily user count`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`SELECT`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`order_date`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` COUNT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`DISTINCT`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer_id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`AS`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` user_count`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`GROUP BY`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 1`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`This query prepares the user count on a daily level. However, if would need distinct user count `,_jsx(_components.em,{children:`per month`}),` this query would not suffice.\nInstead, would need to create a different query:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`6`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- monthly user count`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`SELECT`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` DATE_TRUNC(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`month`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`order_date`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`as`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` order_month,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` COUNT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`DISTINCT`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer_id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`AS`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` user_count`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`GROUP BY`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 1`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`More complexity would create more queries:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`20`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`20`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- a basic user activity report for Tableau`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`CREATE`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` VIEW`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` user_report`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` AS`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- user counts by geography and day`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`SELECT`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` customer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`geography`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`order_date`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` COUNT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`DISTINCT`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer_id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`AS`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` user_count`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`JOIN`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` customer`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`ON`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer_id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` customer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer_id`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`GROUP BY`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` customer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`geography`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`order_date`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`UNION ALL`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- total user counts by day across all geographies`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`SELECT`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` NULL`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` as`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` geography`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`order_date`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` COUNT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`DISTINCT`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer_id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`AS`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` user_count`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`GROUP BY`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`order_date`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`semantic-layer-for-bi`,children:`Semantic Layer for BI`}),`\n`,_jsx(_components.p,{children:`The Honeydew semantic layer operates differently:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Set the `,_jsx(_components.a,{href:`/modeling/relations`,children:`relationship`}),` between `,_jsx(_components.code,{children:`sales`}),` and `,_jsx(_components.code,{children:`customer`}),`, connected on `,_jsx(_components.code,{children:`customer_id`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`Create a `,_jsx(_components.code,{children:`user_count`}),` `,_jsx(_components.a,{href:`/calculations/metrics`,children:`metric`}),` defined as `,_jsx(_components.code,{children:`COUNT(DISTINCT sales.customer_id)`}),`. Note the definition of a metric is a standalone function that can aggregate data.`]}),`\n`,_jsxs(_components.li,{children:[`Connect Tableau via a `,_jsx(_components.a,{href:`/integration/sql-interface`,children:`virtual table`})]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Instead of operating on the `,_jsx(_components.code,{children:`user_report`}),` view, Tableau would now operate on a virtual table called `,_jsx(_components.code,{children:`world`}),`.`]}),`\n`,_jsx(Tip,{children:_jsx(_components.p,{children:`Honeydew presents itself to any user tool as a virtual “flat” table.`})}),`\n`,_jsx(_components.p,{children:`A widget showing users by day and geography will run`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`8`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`8`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- customer count by day and geography`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`SELECT`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"customer.geography\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"sales.order_date\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"sales.user_count\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- world is a virtual table from Honeydew`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` world`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`GROUP BY`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 1`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`2`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`It would actually run a query that joins `,_jsx(_components.code,{children:`sales`}),` and `,_jsx(_components.code,{children:`customer`}),` and builds the `,_jsx(_components.code,{children:`user_count`}),` aggregation accordingly.`]}),`\n`,_jsxs(Tip,{children:[_jsxs(_components.p,{children:[`Note that the query uses `,_jsx(_components.code,{children:`SUM`}),` as an aggregation. The `,_jsx(_components.code,{children:`user_count`}),` metric is actually a distinct count, but the tool that sends the `,_jsx(_components.code,{children:`SUM`}),` does not know that.`]}),_jsxs(_components.p,{children:[`That means that `,_jsx(_components.code,{children:`user_count`}),` is a virtual aggregation - Honeydew translates the `,_jsx(_components.code,{children:`SUM`}),` to the right implementation automatically.`]})]}),`\n`,_jsx(_components.p,{children:`Another widget that only wants monthly totals would call`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`7`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`7`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- customer count by day and geography`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`SELECT`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` DATE_TRUNC(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`month`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"sales.order_date\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`as`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` order_month,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"sales.user_count\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- world is a virtual table from Honeydew`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` world`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`GROUP BY`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 1`})]}),`\n`]})})}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:`With a semantic layer, build the components of a view (the aggregations, the joins) instead of the view itself.`}),_jsx(_components.p,{children:`That means that those components can be reused for infinite number of ad-hoc questions, instead of the specific one that a view query was built for.`})]}),`\n`,_jsx(Heading,{level:`2`,id:`differences-in-modeling`,children:`Differences in Modeling`}),`\n`,_jsx(_components.p,{children:`When modeling a SQL query, it is typical to think of modeling as a pipeline:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsx(_components.li,{children:`Transform the staging data to do X`}),`\n`,_jsx(_components.li,{children:`Transform that result to do Y`}),`\n`,_jsx(_components.li,{children:`Transform that result to do what the user asked for`}),`\n`]}),`\n`,_jsx(_components.p,{children:`When modeling a semantic layer, is it typical to think the other way around:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsx(_components.li,{children:`What metrics \u0026 dimensions that users wants?`}),`\n`,_jsx(_components.li,{children:`What components can be used to build them?`}),`\n`,_jsx(_components.li,{children:`What data is missing to build those?`}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`from-sql-to-honeydew-entities`,children:`From SQL to Honeydew Entities`}),`\n`,_jsx(Heading,{level:`3`,id:`select`,children:`SELECT`}),`\n`,_jsx(_components.p,{children:`A select statement in SQL creates a single query. In a semantic layer however you build the components of a SELECT (its joins, sources, calculations) separately, and then re-use them.`}),`\n`,_jsxs(Tip,{children:[_jsxs(_components.p,{children:[`To create a specific SELECT query from components, use the `,_jsx(_components.em,{children:`Playground`}),` in Honeydew UI or a user entity in Honeydew must have like a SQL client `,_jsx(_components.a,{href:`/integration/sql-interface`,children:`connected to Honeydew`}),`.`]}),_jsx(_components.p,{children:`It is very common to build components (like the calculation of user count) and then test them (by day, by month, by geography) in the playground.`})]}),`\n`,_jsx(Heading,{level:`3`,id:`entities-from-…`,children:`Entities: FROM …`}),`\n`,_jsxs(_components.p,{children:[`A granular table used in a SQL query corresponds to an `,_jsx(_components.a,{href:`/modeling/entities`,children:`Entity`}),` in Honeydew.`]}),`\n`,_jsx(_components.p,{children:`Entities can be based on a table or a view in the data warehouse, or on a custom SQL query.`}),`\n`,_jsxs(Note,{children:[_jsx(_components.p,{children:`An entity in Honeydew must have a primary key defined.`}),_jsx(_components.p,{children:`Users typically map into Honeydew only tables with a unique key, such as facts and dimensions.`}),_jsx(_components.p,{children:`If there isn’t a primary or a unique key present in a table, must create a key as part of the data preparation.`})]}),`\n`,_jsx(Heading,{level:`4`,id:`union`,children:`UNION`}),`\n`,_jsx(_components.p,{children:`Honeydew does not support unions as an entity source.`}),`\n`,_jsx(_components.p,{children:`However, it is possible to create an entity with a custom SQL query that performs a UNION:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`SELECT`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` *`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` usa_inventory`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`UNION ALL`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`SELECT`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` *`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ind_inventory`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`relationships-join-on-…`,children:`Relationships: JOIN ON …`}),`\n`,_jsx(_components.p,{children:`SQL queries join multiple tables together.`}),`\n`,_jsxs(_components.p,{children:[`Joins in Honeydew are defined once as `,_jsx(_components.a,{href:`/modeling/relations`,children:`Relationships`}),` between entities.`]}),`\n`,_jsx(_components.p,{children:`Relationships have similar properties to join such as:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Join fields`}),`: which fields connect the tables. Note there might be multiple fields (called a composite connection), or a calculation used for the join.\nHoneydew allows to use multiple fields to join and/or build and use `,_jsx(_components.a,{href:`/calculations/attributes`,children:`calculated attributes`}),` to join on calculations.`]}),`\n`,_jsx(Warning,{children:_jsx(_components.p,{children:`Honeydew does not support range joins, only equality joins.`})}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Join Type`}),`: part of the relationship definition in Honeydew is the type of join - `,_jsx(_components.code,{children:`INNER`}),`, `,_jsx(_components.code,{children:`LEFT`}),`, `,_jsx(_components.code,{children:`RIGHT`}),` or `,_jsx(_components.code,{children:`FULL OUTER`}),`.`]}),`\n`,_jsxs(Note,{children:[_jsx(_components.p,{children:`Unlike queries, once a join type is set in the semantic layer all joins will use the chosen join type.`}),_jsx(_components.p,{children:`Customizing join type in a specific metric calculation is a planned future extension.`})]}),`\n`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`There are also properties that have no equivalence to a query JOIN condition.`}),`\n`,_jsx(_components.p,{children:`Those properties affect how the calculation is done after the JOIN is made:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Direction`}),`: whether its a one-to-many or a many-to-one join.`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`The direction of the join lets Honeydew know which rows will get duplicated after the join was done. Using that knowledge, Honeydew can\ncorrectly account for duplicated rows when aggregating the data.`}),`\n`,_jsxs(_components.li,{children:[`Many-to-many relations require a `,_jsx(_components.a,{href:`/modeling/relations#modeling-many-many-relations`,children:`connecting table`}),`.`]}),`\n`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Cross-filtering`}),`:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.a,{href:`/modeling/relations#cross-filtering`,children:`cross filtering`}),`) of a join lets Honeydew know whether filters travel through that join.`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[`Typically, in SQL, filters (`,_jsx(_components.code,{children:`WHERE`}),`) are performed after joins, so a field in one table can filter other tables.\nHowever, in a semantic layer might want to control whether filters on table X affect table Y or not.`]}),`\n`,_jsx(_components.p,{children:`One particular application is when joining facts and dimensions: should a filter on one dimension affect another\ndimension when joined through the fact?`}),`\n`,_jsx(_components.p,{children:`The default is “both” which behaves like a SQL query where all filters affect all tables.`}),`\n`]}),`\n`]}),`\n`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`from-sql-to-honeydew-attributes`,children:`From SQL to Honeydew Attributes`}),`\n`,_jsx(Heading,{level:`3`,id:`attributes-…-as-field`,children:`Attributes: … AS field`}),`\n`,_jsx(_components.p,{children:`SQL queries include calculations, for example:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`3`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`SELECT`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` DATE_TRUNC(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`month`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_date`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`as`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` sales_month`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` sales`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Those calculation create new columns within a query. The equivalent in a semantic layer is a\n`,_jsx(_components.a,{href:`/calculations/attributes`,children:`calculated attribute`}),` in a Honeydew entity.`]}),`\n`,_jsx(_components.p,{children:`Calculated attributes as SQL snippets that create “virtual columns” in entities:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_month_num`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` MONTH`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_date`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Those fields can be `,_jsx(_components.em,{children:`reused`}),` for other fields, for example:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`is_q4`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_month_num`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` BETWEEN`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 10`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` AND`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 12`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`window-functions`,children:`Window Functions`}),`\n`,_jsx(_components.p,{children:`Calculated attributes can include window functions. Those window functions treat their entity as the table:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`cumulative_customer_sales`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`OVER`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`PARTITION`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` BY`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer_id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` ORDER BY`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`order_date`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`]})})}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:`Window functions serve specific use cases that requires calculations between rows in the same entity, such as building sessions\nor cumulative sums.`}),_jsx(_components.p,{children:`Most aggregation use cases are served better by building metrics - see below.`})]}),`\n`,_jsx(Heading,{level:`3`,id:`multi-table-attributes`,children:`Multi-table attributes`}),`\n`,_jsx(_components.p,{children:`Calculated attributes in Honeydew can operate over more than one table.`}),`\n`,_jsxs(_components.p,{children:[`For example, if there is a `,_jsx(_components.code,{children:`product`}),` entity that is related (directly or indirectly) to a `,_jsx(_components.code,{children:`sales`}),` entity, then can create:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`discount`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` product`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`unit_price`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` -`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`net_price`})]}),`\n`]})})}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:`Relationships and joins in Honeydew are automatically resolved.`}),_jsx(_components.p,{children:`Every expression can assume that all entities are accessible to it, and Honeydew will join as needed.`}),_jsx(_components.p,{children:`Expression that are impossible to compute (because there is no possible join to perform) would result in an error`})]}),`\n`,_jsx(Heading,{level:`2`,id:`from-sql-to-honeydew-metrics`,children:`From SQL to Honeydew Metrics`}),`\n`,_jsx(Tip,{children:_jsx(_components.p,{children:`Metrics is where SQL and Honeydew differ the most.`})}),`\n`,_jsx(Heading,{level:`3`,id:`basic-aggregations`,children:`Basic Aggregations`}),`\n`,_jsx(_components.p,{children:`SQL does not have the concept of a standalone aggregation function. Aggregations in SQL always operate in a specific context (of a GROUP BY or a WHERE)`}),`\n`,_jsxs(_components.p,{children:[`In a semantic layer like Honeydew a `,_jsx(_components.a,{href:`/calculations/metrics`,children:`metric`}),` is a first-class citizen - a reusable custom aggregation function.`]}),`\n`,_jsx(_components.p,{children:`A basic metric is built like this:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`total_sales`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`3`,id:`multi-table-metrics`,children:`Multi-table Metrics`}),`\n`,_jsx(_components.p,{children:`Metrics in Honeydew can use more than one table (entity).`}),`\n`,_jsxs(_components.p,{children:[`For example this metrics uses both the `,_jsx(_components.code,{children:`sales`}),` entity and the `,_jsx(_components.code,{children:`product`}),` entity:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`total_cost`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`quantity`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` *`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` product`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`unit_price`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`]})})}),`\n`,_jsx(Tip,{children:_jsx(_components.p,{children:`Honeydew resolves relationships automatically, performing joins as needed.`})}),`\n`,_jsx(Heading,{level:`3`,id:`derived-metrics`,children:`Derived Metrics`}),`\n`,_jsx(_components.p,{children:`If a basic metric in Honeydew is an aggregation, a derived metric is one that is built from other metrics.`}),`\n`,_jsx(_components.p,{children:`For example, can create this set of metrics:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`7`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`7`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- basic metrics`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`total_cost`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`quantity`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` *`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` product`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`unit_price`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`total_amount`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- a profit metric is composed from two other metrics`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`profit`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`total_amount`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` -`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`total_cost`})]}),`\n`]})})}),`\n`,_jsx(Tip,{children:_jsx(_components.p,{children:`There is no limit on metric composition: stack and reuse metrics in any way`})}),`\n`,_jsx(Heading,{level:`4`,id:`user-context`,children:`User Context`}),`\n`,_jsxs(_components.p,{children:[`Metrics are sensitive to the `,_jsx(_components.a,{href:`/calculations/metrics#sensitivity-to-user-context`,children:`user query context`}),`.`]}),`\n`,_jsx(_components.p,{children:`That means that the computed result of a metric would depend on the query - the filters and groups in use.`}),`\n`,_jsx(_components.p,{children:`User context includes:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`Filtering - filters that come from a user query`}),`\n`,_jsx(_components.li,{children:`Grouping - groups that come from a user query`}),`\n`]}),`\n`,_jsx(_components.p,{children:`Metrics in Honeydew can change the user context for their calculation, applying additional filters or changing group by.`}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:`It’s easy to think of each metric calculated in a Honeydew generated query as its own CTE.`}),_jsxs(_components.p,{children:[`By default, the CTE to calculate a metric would use the `,_jsx(_components.code,{children:`GROUP BY`}),` the user has asked for in the query, and would operate\non the data as it was filtered by the user.`]}),_jsxs(_components.p,{children:[`But what if want a particular metric to be calculated with a different `,_jsx(_components.code,{children:`GROUP BY`}),`? Or have another `,_jsx(_components.code,{children:`WHERE`}),` condition?`]}),_jsx(_components.p,{children:`That is changing the user context for the metric.`})]}),`\n`,_jsx(Heading,{level:`4`,id:`sum-case-when-…-filtered-metrics`,children:`SUM(CASE WHEN …) - Filtered Metrics`}),`\n`,_jsxs(_components.p,{children:[`A common pattern in SQL is to use `,_jsx(_components.code,{children:`CASE WHEN`}),` to create a filtered aggregation:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`red_sales_amount`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`CASE`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` WHEN`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` product`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`color`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'Red'`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` THEN`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` ELSE`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 0`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` END`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`A filtered aggregation adds a filter on top of the user context.`}),`\n`,_jsxs(_components.p,{children:[`Honeydew offers a different way called a `,_jsx(_components.a,{href:`/calculations/metrics#filtered-metrics`,children:`filter qualifier`}),` to apply filters\nto metrics that are already defined:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`5`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- a basic metric`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`total_amount`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- a derived filtered metric`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`red_sales_amount`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` FILTER`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`WHERE`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` product`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`color`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'Red'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`Filter qualifiers enable to create filtered metrics over any aggregation.`}),`\n`,_jsxs(Tip,{children:[_jsxs(_components.p,{children:[`The default value for `,_jsx(_components.code,{children:`SUM`}),` and `,_jsx(_components.code,{children:`COUNT`}),` aggregations where there is no data available is automatically 0.`]}),_jsxs(_components.p,{children:[`Other aggregations will have `,_jsx(_components.code,{children:`NULL`}),` as the value for an empty dataset.`]}),_jsxs(_components.p,{children:[`Default values can also be `,_jsx(_components.a,{href:`/calculations/metrics#default-value`,children:`controlled explicitly`}),` using the `,_jsx(_components.code,{children:`DEFAULT`}),` qualifier -`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`red_sales_amount`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` FILTER`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`WHERE`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` product`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`color`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'Red'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`DEFAULT`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 0`})]}),`\n`]})})})]}),`\n`,_jsx(_components.p,{children:`Filter qualifiers can also apply directly to aggregations:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`3`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- a filtered metric on an aggregation`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`red_sales_amount`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FILTER`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`WHERE`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` product`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`color`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'Red'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`]})})}),`\n`,_jsx(Tip,{children:_jsxs(_components.p,{children:[`It’s always recommended to use `,_jsx(_components.code,{children:`FILTER (WHERE ...)`}),` rather than a `,_jsx(_components.code,{children:`CASE WHEN`}),` in an aggregation - as that allows Honeydew\nto sometimes construct a more efficient query`]})}),`\n`,_jsx(Heading,{level:`4`,id:`build-ratios-by-combining-filtered-metrics`,children:`Build Ratios by Combining Filtered Metrics`}),`\n`,_jsx(_components.p,{children:`A common pattern in SQL is using the same aggregation with different filters in order to build a combined metric, like a ratio.`}),`\n`,_jsx(_components.p,{children:`Consider the following SQL statement:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`13`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`13`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- SQL query for sales of red products out of all product sales`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`SELECT`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`order_date`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` DIV0(`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` -- Aggregate over red rows`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`CASE`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` WHEN`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` product`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`color`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'Red'`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` THEN`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` END`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`),`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` -- Aggregate over all rows`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`as`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` red_sales_out_of_all_sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`LEFT JOIN`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` product`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`ON`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`product_id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` product`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`product_id`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`GROUP BY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` order_date`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`The equivalent in Honeydew would be a derived metric:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`6`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- a ratio metric for red sales`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`red_sales_ratio`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`DIV0(`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`total_amount`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` FILTER`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`WHERE`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` product`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`color`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'Red'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`),`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`total_amount`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Can also use the `,_jsx(_components.code,{children:`sales.red_sales_amount`}),` defined above for the same result:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`6`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`red_sales_ratio`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- a ratio metric for red sales`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`DIV0(`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`red_sales_amount`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`total_amount`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})}),`\n`]})})}),`\n`,_jsx(Tip,{children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`DIV0`}),` is usually preferred to a division operator as it can gracefully handle division by zero.`]})}),`\n`,_jsx(_components.p,{children:`This derived metric perform two actions:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsx(_components.li,{children:`The numerator is aggregating the sales amount only on red product rows (note that happens after applying any user filters supplied in the query)`}),`\n`,_jsx(_components.li,{children:`The denominator is aggregating the sales amount over all products`}),`\n`]}),`\n`,_jsx(Tip,{children:_jsxs(_components.p,{children:[`The actual aggregation (how `,_jsx(_components.code,{children:`sales.total_amount`}),` is calculated) is defined once, and reused in the derived metric twice.`]})}),`\n`,_jsx(Heading,{level:`4`,id:`group-by-control-grouping`,children:`GROUP BY - Control Grouping`}),`\n`,_jsxs(_components.p,{children:[`Metrics in Honeydew can also `,_jsx(_components.a,{href:`/calculations/metrics#controlling-grouping`,children:`change the user grouping context`}),`.`]}),`\n`,_jsx(_components.p,{children:`Consider the following SQL statement that compares a total aggregation to an aggregation over a partial segment:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`20`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`20`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- SQL query for product % contribution to total sales`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`WITH`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`total_sales `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`AS`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` SELECT`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`as`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` total_sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` sales`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`),`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`product_sales `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`AS`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` SELECT`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` product`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`product_id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`as`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` product_sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` LEFT JOIN`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` product`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` ON`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`product_id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` product`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`product_id`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` GROUP BY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` product_id`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`SELECT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` product_id,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` DIV0(product_sales, total_sales) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`as`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` product_contribution_to_total`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` total_sales, product_sales`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`How would you build a similar metric in Honeydew?`}),`\n`,_jsxs(_components.p,{children:[`Let’s build a metric in Honeydew that is even more dynamic: `,_jsx(_components.em,{children:`the % contribution to total sales of any user group`}),`. It can contribution of a product, or it can be any other group.`]}),`\n`,_jsx(_components.p,{children:`That metric would be:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`6`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- Honeydew metric`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`contribution_to_total`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`DIV0(`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`total_amount`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`total_amount`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` GROUP BY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ()`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`This derived metric perform two actions:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsx(_components.li,{children:`The numerator is grouped by the user’s grouping (can be by product or otherwise)`}),`\n`,_jsx(_components.li,{children:`The denominator is grouped by nothing, removing any user groups`}),`\n`]}),`\n`,_jsxs(Tip,{children:[_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`GROUP BY (...)`}),` qualifier sets the grouping for a metric. It can be nothing (as in the example above),\nor it can be specific:`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`6`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- Honeydew metric`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`contribution_to_yearly_sales`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`DIV0(`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`total_amount`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`total_amount`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` GROUP BY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`date`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`year`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})}),`\n`]})})})]}),`\n`,_jsx(Heading,{level:`4`,id:`nested-multi-level-aggregation`,children:`Nested (Multi-Level) Aggregation`}),`\n`,_jsxs(_components.p,{children:[`Another way to `,_jsx(_components.a,{href:`/calculations/metrics#controlling-grouping`,children:`change the user grouping context`}),` is nesting aggregations.`]}),`\n`,_jsx(_components.p,{children:`Consider the following SQL statement:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`16`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`16`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- SQL query for average daily sales for each product`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`WITH`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`daily_product_sales `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`AS`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` SELECT`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` product`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`product_id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`order_date`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`as`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` daily_product_sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` LEFT JOIN`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` product`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` ON`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`product_id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` product`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`product_id`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` GROUP BY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` product_id, order_date`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`SELECT`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` product_id,`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` AVG`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(daily_product_sales) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`as`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` daily_avg_product_sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` daily_product_sales`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`How would you build a similar metric in Honeydew?`}),`\n`,_jsxs(_components.p,{children:[`But one that is more dynamic: `,_jsx(_components.em,{children:`one that can adjust to any user group`})]}),`\n`,_jsx(_components.p,{children:`That metric would be:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- Honeydew metric`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`avg_daily_sales`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` AVG`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`( `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`total_sales`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` GROUP BY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`*`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`order_date`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) )`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`This derived metric performs two actions:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsx(_components.li,{children:`The internal aggregation is grouped by the user’s grouping + date`}),`\n`,_jsx(_components.li,{children:`The external aggregation is grouped by the user’s grouping only`}),`\n`]}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:`If that metric is grouped by product, the result would be average daily product sales.`}),_jsx(_components.p,{children:`If that metric is grouped by customer segment, the result would be average daily segment sales.`}),_jsx(_components.p,{children:`If that metric is grouped by product and customer segment, the result would be average daily sales per product, per segment.`})]}),`\n`,_jsx(Heading,{level:`4`,id:`having-using-metrics-as-filters`,children:`HAVING - Using Metrics as Filters`}),`\n`,_jsxs(_components.p,{children:[`Metric in Honeydew can also be used as filters for further calculations, similar to how `,_jsx(_components.code,{children:`HAVING`}),` operates in SQL.`]}),`\n`,_jsx(_components.p,{children:`Consider the following SQL statement:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`18`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`18`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- SQL query for average sale amount, ignoring products with less than $100 in daily sales`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- list products that had more than $100 in sales per day`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`WITH`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` daily_active_products `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`AS`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` SELECT`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`order_date`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`product_id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` GROUP BY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ALL`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` HAVING`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 100`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- average sale amount by state, only for products that had >$100 daily sales volume`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`SELECT`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` location`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`state`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` AVG`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`as`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` avg_sales_of_active_products`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`INNER JOIN`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` daily_active_products `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`ON`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`product_id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` daily_active_products`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`product_id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` AND`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`order_date`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` daily_active_products`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`order_date`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`LEFT JOIN`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` location`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` ON`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`location_id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` location`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`location_id`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`That calculates average sales of active products per state.`}),`\n`,_jsxs(_components.p,{children:[`The equivalent Honeydew metric would be `,_jsx(_components.em,{children:`dynamic to any user choice of a grouping`}),`, allowing to slice average sales of active products by location or any\nother user grouping choice.`]}),`\n`,_jsx(_components.p,{children:`That expression would be a filtered metric based on a metric:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`7`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`7`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`avg_sales_of_active_products`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- Honeydew metric for average sale amount for active products`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`AVG`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FILTER`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`WHERE`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`total_amount`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` GROUP BY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`order_date`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`product_id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 100`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})}),`\n`]})})}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`The `,_jsx(_components.code,{children:`sales.total_amount`}),` metric is used in the filter with a specific grouping (daily products) and a filter (over $100 in sales)`]}),`\n`,_jsxs(_components.li,{children:[`The external aggregation is an `,_jsx(_components.code,{children:`AVG`}),` that operates on any data that passed the internal filter.`]}),`\n`]}),`\n`,_jsxs(Tip,{children:[_jsxs(_components.p,{children:[`If the metric above is used in a `,_jsx(_components.a,{href:`/integration/sql-interface`,children:`query`}),` that groups by `,_jsx(_components.code,{children:`location.state`}),` then it would return it grouped by state.`]}),_jsx(_components.p,{children:`It can also be used with any other grouping!`})]}),`\n`,_jsx(Heading,{level:`3`,id:`with-…-ctes`,children:`WITH … (CTEs)`}),`\n`,_jsx(_components.p,{children:`CTEs in SQL are commonly used to create aggregated data as part of a larger calculation, for example:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`20`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`20`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- sales per customer`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`WITH`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` customer_sales `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`AS`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` SELECT`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` customer_id,`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`as`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` customer_sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` JOIN`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` customer`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` ON`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer_id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer_id`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` GROUP BY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` customer_id`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- average customer sales by customer type`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- customer type - VIP for customers with >$1000 of total sales`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`SELECT`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` CASE`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` WHEN`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` cs`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer_sales`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` >`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 1000`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` THEN`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"VIP\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` ELSE`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"NOT VIP\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` END`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` AS`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` customer_type`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` AVG`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`cs`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer_sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`as`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` avg_customer_sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`FROM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` customer`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`JOIN`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` customer_sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`ON`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` customer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer_id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` customer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer_id`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`GROUP BY`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 1`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`Calculated attributes in Honeydew can use metrics, which is a very common translation for CTEs.`}),`\n`,_jsx(_components.p,{children:`The equivalent for that expression would be a calculated attribute in customer:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- calculated attribute in Honeydew customer entity`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer_sales`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`]})})}),`\n`,_jsx(Tip,{children:_jsxs(_components.p,{children:[`If a calculated attribute in entity uses an aggregation, then that aggregation is grouped to the\nentity primary key (`,_jsx(_components.code,{children:`customer_id`}),` in the example above).`]})}),`\n`,_jsx(_components.p,{children:`And a derived attribute`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- calculated attribute in Honeydew customer entity`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer_type`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` CASE`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` customer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer_sales`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` >`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 1000`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` THEN`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"VIP\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` ELSE`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"NOT VIP\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` END`})]}),`\n`]})})}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:`A better deconstruction for that CTE would build a metric for sales:`}),_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`--- metric in Honeydew sales entity`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`total_sales`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`sales_amount`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`]})})}),_jsx(_components.p,{children:`And reuse the metric in the customer entity`}),_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`--- calculated attribute in Honeydew customer entity`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`customer_sales`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` sales`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`total_sales`})]}),`\n`]})})}),_jsx(_components.p,{children:`That would behave the same way as using the aggregation.`})]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"From SQL to Honeydew","description":null,"href":"/migration/sql-guide"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Introduction","slug":"introduction","depth":2,"children":[]},{"title":"VIEWs vs Semantic Layer","slug":"views-vs-semantic-layer","depth":2,"children":[{"title":"SQL Queries for BI","slug":"sql-queries-for-bi","depth":3,"children":[]},{"title":"Semantic Layer for BI","slug":"semantic-layer-for-bi","depth":3,"children":[]}]},{"title":"Differences in Modeling","slug":"differences-in-modeling","depth":2,"children":[]},{"title":"From SQL to Honeydew Entities","slug":"from-sql-to-honeydew-entities","depth":2,"children":[{"title":"SELECT","slug":"select","depth":3,"children":[]},{"title":"Entities: FROM …","slug":"entities-from-…","depth":3,"children":[]},{"title":"UNION","slug":"union","depth":4,"children":[]},{"title":"Relationships: JOIN ON …","slug":"relationships-join-on-…","depth":3,"children":[]}]},{"title":"From SQL to Honeydew Attributes","slug":"from-sql-to-honeydew-attributes","depth":2,"children":[{"title":"Attributes: … AS field","slug":"attributes-…-as-field","depth":3,"children":[]},{"title":"Window Functions","slug":"window-functions","depth":3,"children":[]},{"title":"Multi-table attributes","slug":"multi-table-attributes","depth":3,"children":[]}]},{"title":"From SQL to Honeydew Metrics","slug":"from-sql-to-honeydew-metrics","depth":2,"children":[{"title":"Basic Aggregations","slug":"basic-aggregations","depth":3,"children":[]},{"title":"Multi-table Metrics","slug":"multi-table-metrics","depth":3,"children":[]},{"title":"Derived Metrics","slug":"derived-metrics","depth":3,"children":[]},{"title":"User Context","slug":"user-context","depth":4,"children":[]},{"title":"SUM(CASE WHEN …) - Filtered Metrics","slug":"sum-case-when-…-filtered-metrics","depth":4,"children":[]},{"title":"Build Ratios by Combining Filtered Metrics","slug":"build-ratios-by-combining-filtered-metrics","depth":4,"children":[]},{"title":"GROUP BY - Control Grouping","slug":"group-by-control-grouping","depth":4,"children":[]},{"title":"Nested (Multi-Level) Aggregation","slug":"nested-multi-level-aggregation","depth":4,"children":[]},{"title":"HAVING - Using Metrics as Filters","slug":"having-using-metrics-as-filters","depth":4,"children":[]},{"title":"WITH … (CTEs)","slug":"with-…-ctes","depth":3,"children":[]}]}],"codeExamples":{}},"jsLinks":["/docs/_mintlify/custom/honeydew/82b3c90683bc6a9d/script.js"],"subdomain":"honeydew","siteName":"Honeydew Documentation","title":"From SQL to Honeydew - Honeydew Documentation","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-29T12:57:31.453Z","originalFileLocation":"migration/sql-guide.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"application-name\" content=\"Honeydew Documentation\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"From SQL to Honeydew - Honeydew Documentation\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Honeydew Documentation\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://honeydew.ai/docs/migration/sql-guide\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://honeydew.mintlify.app/_mintlify/api/og/v2?division=Semantic+Ecosystem\u0026amp;title=From+SQL+to+Honeydew\u0026amp;theme=0b845200c1ca80fd78144b6a\u0026amp;signature=dae085efd45702a96c418434868dc29594d1e20b031423944060b3763c39014d\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"From SQL to Honeydew - Honeydew Documentation\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://honeydew.mintlify.app/_mintlify/api/og/v2?division=Semantic+Ecosystem\u0026amp;title=From+SQL+to+Honeydew\u0026amp;theme=0b845200c1ca80fd78144b6a\u0026amp;signature=dae085efd45702a96c418434868dc29594d1e20b031423944060b3763c39014d\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Honeydew Documentation\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#abcb1a\">\u003clink data-mint-head rel=\"canonical\" href=\"https://honeydew.ai/docs/migration/sql-guide\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/docs/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/docs/migration/sql-guide.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://honeydew.ai/#organization\",\"name\":\"Honeydew Documentation\",\"url\":\"https://honeydew.ai\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/honeydew/FY_ZgBcPUZJ2-No3/logo/logo.svg?fit=max\u0026auto=format\u0026n=FY_ZgBcPUZJ2-No3\u0026q=85\u0026s=10dbf238c7bdb5bb1ee94e85eea8049f\"}},{\"@type\":\"WebSite\",\"@id\":\"https://honeydew.ai/docs#website\",\"name\":\"Honeydew Documentation\",\"url\":\"https://honeydew.ai/docs\",\"publisher\":{\"@id\":\"https://honeydew.ai/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://honeydew.ai/docs/migration/sql-guide#webpage\",\"url\":\"https://honeydew.ai/docs/migration/sql-guide\",\"name\":\"From SQL to Honeydew\",\"dateModified\":\"2026-10-29T12:57:31.453Z\",\"isPartOf\":{\"@id\":\"https://honeydew.ai/docs#website\"},\"breadcrumb\":{\"@id\":\"https://honeydew.ai/docs/migration/sql-guide#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://honeydew.ai/docs/migration/sql-guide#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Semantic Ecosystem\",\"item\":\"https://honeydew.ai/docs/integration/apache-ossie-osi\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"From SQL to Honeydew\",\"item\":\"https://honeydew.ai/docs/migration/sql-guide\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://honeydew.ai/docs/migration/sql-guide#article\",\"headline\":\"From SQL to Honeydew\",\"name\":\"From SQL to Honeydew\",\"url\":\"https://honeydew.ai/docs/migration/sql-guide\",\"mainEntityOfPage\":{\"@id\":\"https://honeydew.ai/docs/migration/sql-guide#webpage\"},\"dateModified\":\"2026-10-29T12:57:31.453Z\",\"publisher\":{\"@id\":\"https://honeydew.ai/#organization\"},\"isPartOf\":{\"@id\":\"https://honeydew.ai/docs#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Honeydew Documentation\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Honeydew Documentation","nav":{"global":null,"groups":[{"group":"Quick Start","pages":[{"title":"Introduction","href":"/introduction"},{"title":"TPC-H Walkthrough","href":"/tpch-example"},{"title":"Evaluation Process","href":"/evaluation"},{"title":"Initial Setup","href":"/initial-setup"},{"title":"Support","href":"/support"}]},{"group":"Semantic Ecosystem","pages":[{"title":"Apache Ossie (OSI)","description":null,"href":"/integration/apache-ossie-osi"},{"title":"From SQL to Honeydew","href":"/migration/sql-guide"},{"title":"From DAX to Honeydew","description":null,"href":"/migration/dax-guide"},{"title":"From Tableau to Honeydew","href":"/migration/tableau-guide"},{"title":"Import Tools","href":"/migration/import-tools"}]},{"group":"Modeling Reference","pages":[{"title":"Architecture","href":"/architecture"},{"title":"Semantic Compiler","href":"/semantic-compiler"},{"group":"Entity Modeling","pages":[{"title":"Entities","href":"/modeling/entities"},{"title":"Source Data","href":"/modeling/source-data"},{"title":"Relations","href":"/modeling/relations"}]},{"title":"Domains","href":"/domains"},{"group":"Calculations","pages":[{"title":"Attributes","href":"/calculations/attributes"},{"title":"Metrics","href":"/calculations/metrics"},{"title":"Filters","href":"/calculations/filters"}]},{"title":"Datasets","href":"/dynamic-datasets"},{"title":"Parameters","href":"/parameters"},{"group":"Advanced Modeling","pages":[{"title":"Order of Filtering","href":"/advanced-modeling/order-of-computation"},{"title":"Multiple Facts and Shared Dimensions","href":"/advanced-modeling/shared-dimensions"},{"title":"Conditional Filtering","href":"/advanced-modeling/conditional-filtering"},{"title":"Multi-Grain Tables","href":"/advanced-modeling/multi-grain-tables"},{"title":"Slowly Changing Dimensions","href":"/advanced-modeling/slowly-changing-dimensions"},{"title":"Time Aware Metrics","href":"/advanced-modeling/time-metrics"},{"title":"Time Spines","href":"/advanced-modeling/time-spines"},{"title":"Handling Fan-Out and Chasm Joins","href":"/advanced-modeling/mixing-granularities"}]},{"group":"Recipes","pages":[{"title":"Overview","href":"/recipes/overview"},{"title":"How much revenue comes from a specific category?","sidebarTitle":"Metric for a specific category","href":"/recipes/category-revenue"},{"title":"What share of revenue comes from a specific category?","sidebarTitle":"Category share of total","href":"/recipes/category-revenue-share"},{"title":"Are our customers coming back?","sidebarTitle":"Active customers \u0026 stickiness","href":"/recipes/active-customers"},{"title":"Are we growing compared to last year?","sidebarTitle":"Period-over-period growth","href":"/recipes/yoy-revenue-growth"},{"title":"Are customers spending more per visit?","sidebarTitle":"Fixed level of detail metric","href":"/recipes/avg-order-value"},{"title":"What fraction of orders exceed a revenue threshold?","sidebarTitle":"Share above a threshold","href":"/recipes/high-value-order-share"},{"title":"Which truck has the most consistent daily sales?","sidebarTitle":"Average per day","href":"/recipes/avg-daily-revenue"},{"title":"Can one metric show different numbers to different teams?","sidebarTitle":"BI parameters","href":"/recipes/dynamic-bi-parameters"},{"title":"How do I give different teams their own governed view of the data?","sidebarTitle":"Domain hierarchy","href":"/recipes/domain-hierarchy"}]},{"title":"YAML Schema","href":"/yaml-schema"}]},{"group":"Context Layer","pages":[{"title":"Overview","href":"/integration/context-layer/overview"},{"title":"Deep Analysis","href":"/integration/context-layer/deep-analysis"},{"title":"Agents","href":"/integration/context-layer/agents"},{"title":"Context Management","href":"/integration/context-layer/context-management"},{"title":"AI Metadata","href":"/integration/context-layer/ai-metadata"},{"title":"Building with AI","href":"/integration/context-layer/building-with-ai"},{"title":"YAML Schema","href":"/integration/context-layer/yaml-schema"}]},{"group":"Management","pages":[{"group":"Performance","pages":[{"title":"Overview","href":"/performance/overview"},{"title":"Aggregate Aware Caching","href":"/performance/aggregate-awareness"},{"title":"Incremental Aggregate Updates","href":"/performance/aggregate-incremental-updates"},{"title":"Entity Caching","href":"/performance/entity-caching"},{"title":"Filtering and Sampling","href":"/performance/filtering-and-sampling"}]},{"group":"Governance","pages":[{"title":"Metadata","href":"/governance/metadata"},{"title":"Git Version Control","href":"/governance/git-version-control"},{"title":"Change Approval","href":"/governance/change-approval"},{"group":"CI/CD Workflow","pages":[{"title":"Overview","href":"/governance/ci-cd/overview"},{"title":"GitHub Actions","icon":"github","href":"/governance/ci-cd/github-actions"}]},{"title":"Workspaces","href":"/governance/workspaces"},{"title":"Environments","href":"/governance/environments"}]},{"group":"Monitoring","pages":[{"title":"Query history","href":"/monitoring/query-history"},{"title":"Question history","href":"/monitoring/question-history"},{"title":"Chat history","href":"/monitoring/chat-history"}]},{"title":"User Access Control","href":"/access-control/user-access-control"},{"title":"Row-Level Security","href":"/security/row-level-security"}]},{"group":"Integrations","pages":[{"title":"MCP Server","href":"/integration/mcp"},{"group":"Interfaces","pages":[{"title":"SQL Interface","href":"/integration/sql-interface"},{"title":"GraphQL API","href":"/integration/graphql-api"},{"title":"XMLA Interface","href":"/integration/xmla-interface"},{"title":"Snowflake Native App","icon":"snowflake","href":"/integration/snowflake-native-app"}]},{"group":"AI","pages":[{"title":"Slack App","icon":"slack","href":"/integration/context-layer/slack-app"},{"title":"Microsoft Teams App","icon":"microsoft","href":"/integration/context-layer/teams-app"},{"title":"Build an Embedded AI Analyst UI","sidebarTitle":"Embedded UI","href":"/integration/context-layer/embedded-ui"},{"title":"Streamlit","href":"/integration/context-layer/streamlit"},{"title":"LLM Providers","href":"/integration/context-layer/llm-providers"}]},{"group":"BI Tools","pages":[{"title":"Supported Tools","href":"/integration/bi-tools/supported-tools"},{"title":"Power BI","href":"/integration/bi-tools/powerbi"},{"title":"Excel","href":"/integration/bi-tools/excel"},{"title":"Tableau","href":"/integration/bi-tools/tableau"},{"title":"Looker","href":"/integration/bi-tools/looker"},{"title":"ThoughtSpot","href":"/integration/bi-tools/thoughtspot"},{"title":"Databricks","href":"/integration/bi-tools/databricks"},{"title":"Sigma","href":"/integration/bi-tools/sigma"},{"title":"Domo","href":"/integration/bi-tools/domo"},{"title":"Qlik","href":"/integration/bi-tools/qlik"},{"title":"Amazon Quick","href":"/integration/bi-tools/amazon-quick"},{"title":"Hex","href":"/integration/bi-tools/hex"},{"title":"Deepnote","href":"/integration/bi-tools/deepnote"},{"title":"Superset/Preset","href":"/integration/bi-tools/superset-preset"},{"title":"Metabase","href":"/integration/bi-tools/metabase"},{"title":"Mode Analytics","href":"/integration/bi-tools/mode"},{"title":"Lightdash","href":"/integration/bi-tools/lightdash"},{"title":"Holistics","href":"/integration/bi-tools/holistics"},{"title":"Redash","href":"/integration/bi-tools/redash"}]},{"group":"Catalogs","pages":[{"title":"Data Catalogs","href":"/integration/catalogs/supported-tools"},{"title":"Atlan","href":"/integration/catalogs/atlan"},{"title":"Collibra","href":"/integration/catalogs/collibra"},{"title":"DataHub","href":"/integration/catalogs/datahub"}]},{"group":"Observability","pages":[{"title":"OpenTelemetry","href":"/integration/observability/opentelemetry"}]},{"group":"SQL Clients","pages":[{"title":"Retool","href":"/integration/bi-tools/retool"},{"title":"Database Tools \u0026 IDEs","href":"/integration/bi-tools/sql-tools-ides"},{"title":"Jupyter","href":"/integration/bi-tools/jupyter"},{"title":"Python","href":"/integration/bi-tools/python"},{"title":"JavaScript","href":"/integration/bi-tools/javascript"}]},{"group":"Data Sources","pages":[{"title":"Snowflake","icon":"snowflake","href":"/integration/data-sources/snowflake"},{"title":"Databricks","href":"/integration/data-sources/databricks"},{"title":"Google BigQuery","icon":"google","href":"/integration/data-sources/bigquery"}]},{"group":"Git","pages":[{"title":"GitHub","icon":"github","href":"/integration/git/github"},{"title":"GitLab","icon":"gitlab","href":"/integration/git/gitlab"},{"title":"Bitbucket","icon":"bitbucket","href":"/integration/git/bitbucket"},{"title":"Azure DevOps","icon":"microsoft","href":"/integration/git/azure-devops"}]},{"group":"ELT Tools","pages":[{"title":"Data Pipeline Architecture","href":"/integration/etl-tools/pipeline-architecture"},{"title":"dbt","href":"/integration/etl-tools/dbt"}]}]},{"group":"Security","pages":[{"title":"Security \u0026 Compliance","href":"/security/security"},{"title":"API Keys","href":"/access-control/api-keys"},{"group":"Authentication","pages":[{"title":"Single Sign-On (SSO)","href":"/access-control/sso"},{"title":"Okta SSO Integration (OIDC)","href":"/access-control/okta"},{"title":"Microsoft Entra ID (formerly Azure Active Directory)","href":"/access-control/entra-id"},{"title":"PingIdentity SSO Integration (SAML)","href":"/access-control/ping-identity"},{"title":"OIDC Provider SSO Integration","href":"/access-control/oidc-provider"},{"title":"SAML Provider SSO Integration","href":"/access-control/saml-provider"},{"title":"Windows Authentication (Kerberos)","href":"/access-control/windows-authentication"}]},{"title":"IP Access Control","href":"/access-control/ip-access-control"},{"title":"Vulnerability Disclosure Policy","href":"/security/vulnerability-disclosure-policy"}]},{"group":"Release Notes","pages":[{"title":"Release Notes","href":"/release-notes"}]}]},"basePath":"","title":"From SQL to Honeydew - Honeydew Documentation","buildId":"dpl_9yaRmq8qi7yyMZn9oEWmKEdYMvGZ","deploymentId":"dpl_9yaRmq8qi7yyMZn9oEWmKEdYMvGZ","dynamics":[],"chunks":[]}