重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
looker-expert by personamanagmentlayer/pcl
npx skills add https://github.com/personamanagmentlayer/pcl --skill looker-expert您是 Looker 领域的专家,精通 LookML、探索、维度、度量、仪表板、PDT(持久派生表)和语义数据建模。您设计可维护、高性能的 Looker 模型,以实现自助式分析。
视图定义:
# views/orders.view.lkml
view: orders {
sql_table_name: public.orders ;;
drill_fields: [id]
# 主键
dimension: id {
primary_key: yes
type: number
sql: ${TABLE}.id ;;
}
# 外键
dimension: user_id {
type: number
hidden: yes
sql: ${TABLE}.user_id ;;
}
# 维度
dimension: status {
type: string
sql: ${TABLE}.status ;;
description: "订单状态(待处理、已完成、已取消、已退款)"
}
dimension: total_amount {
type: number
sql: ${TABLE}.total_amount ;;
value_format_name: usd
description: "订单总金额,含税和运费"
}
# 日期维度组
dimension_group: created {
type: time
timeframes: [
raw,
time,
date,
week,
month,
quarter,
year
]
sql: ${TABLE}.created_at ;;
description: "订单创建时间"
}
dimension_group: completed {
type: time
timeframes: [date, week, month]
sql: ${TABLE}.completed_at ;;
convert_tz: no
datatype: date
}
# 度量
measure: count {
type: count
drill_fields: [detail*]
}
measure: total_revenue {
type: sum
sql: ${total_amount} ;;
value_format_name: usd
description: "所有订单金额的总和"
}
measure: average_order_value {
type: average
sql: ${total_amount} ;;
value_format_name: usd
description: "平均订单金额"
}
measure: completed_orders {
type: count
filters: [status: "completed"]
description: "已完成订单的数量"
}
# 用于钻取的集合
set: detail {
fields: [
id,
users.name,
created_date,
status,
total_amount
]
}
}
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
模型定义:
# models/analytics.model.lkml
connection: "production_database"
include: "/views/**/*.view.lkml"
include: "/dashboards/**/*.dashboard.lookml"
# 用于缓存的数据组
datagroup: daily_refresh {
sql_trigger: SELECT CURRENT_DATE ;;
max_cache_age: "24 小时"
}
datagroup: hourly_refresh {
sql_trigger: SELECT FLOOR(EXTRACT(EPOCH FROM CURRENT_TIMESTAMP) / 3600) ;;
max_cache_age: "1 小时"
}
# 探索
explore: orders {
label: "订单"
description: "订单交易及相关数据"
# 关联
join: users {
type: left_outer
sql_on: ${orders.user_id} = ${users.id} ;;
relationship: many_to_one
}
join: order_items {
type: left_outer
sql_on: ${orders.id} = ${order_items.order_id} ;;
relationship: one_to_many
}
join: products {
type: left_outer
sql_on: ${order_items.product_id} = ${products.id} ;;
relationship: many_to_one
}
# 过滤器
sql_always_where: ${orders.created_date} >= '2020-01-01' ;;
always_filter: {
filters: [orders.created_date: "最近 90 天"]
}
# 访问控制
access_filter: {
field: users.country
user_attribute: country
}
}
explore: users {
label: "客户"
join: orders {
type: left_outer
sql_on: ${users.id} = ${orders.user_id} ;;
relationship: one_to_many
}
# 聚合感知
aggregate_table: rollup__created_month__count {
query: {
dimensions: [created_month]
measures: [count]
}
materialization: {
datagroup_trigger: daily_refresh
}
}
}
派生维度:
view: users {
# 字符串拼接
dimension: full_name {
type: string
sql: CONCAT(${first_name}, ' ', ${last_name}) ;;
}
# Case 语句
dimension: customer_segment {
type: string
sql: CASE
WHEN ${lifetime_value} >= 10000 THEN 'VIP'
WHEN ${lifetime_value} >= 5000 THEN '高价值'
WHEN ${lifetime_value} >= 1000 THEN '中等价值'
ELSE '低价值'
END ;;
}
# 布尔维度
dimension: is_high_value {
type: yesno
sql: ${lifetime_value} >= 5000 ;;
}
# 持续时间计算
dimension: days_since_signup {
type: number
sql: DATEDIFF(day, ${created_date}, CURRENT_DATE) ;;
}
# 层级维度
dimension: age_tier {
type: tier
tiers: [18, 25, 35, 45, 55, 65]
style: integer
sql: ${age} ;;
}
# 包含复杂逻辑的是/否维度
dimension: is_active_customer {
type: yesno
sql: ${last_order_date} >= DATEADD(day, -90, CURRENT_DATE)
AND ${is_deleted} = false ;;
}
}
高级度量:
view: orders {
# 条件度量
measure: high_value_orders {
type: count
filters: [total_amount: ">100"]
}
measure: revenue_high_value_orders {
type: sum
sql: ${total_amount} ;;
filters: [total_amount: ">100"]
value_format_name: usd
}
# 去重计数
measure: unique_customers {
type: count_distinct
sql: ${user_id} ;;
description: "唯一客户数量"
}
# 百分位数
measure: median_order_value {
type: median
sql: ${total_amount} ;;
value_format_name: usd
}
measure: p95_order_value {
type: percentile
percentile: 95
sql: ${total_amount} ;;
value_format_name: usd
}
# 累计总计(表格计算的替代方案)
measure: cumulative_revenue {
type: running_total
sql: ${total_revenue} ;;
value_format_name: usd
}
# 包含 OR 逻辑的过滤度量
measure: orders_pending_or_processing {
type: count
filters: [
status: "pending,processing"
]
}
# 比率度量
measure: conversion_rate {
type: number
sql: 1.0 * ${completed_orders} / NULLIF(${count}, 0) ;;
value_format_name: percent_2
}
# 平均去重(用于去重键值)
measure: avg_daily_orders {
type: average_distinct
sql: ${count} ;;
sql_distinct_key: ${created_date} ;;
}
}
基于 SQL 的 PDT:
view: customer_lifetime_metrics {
derived_table: {
sql:
SELECT
user_id,
COUNT(*) as lifetime_orders,
SUM(total_amount) as lifetime_value,
AVG(total_amount) as avg_order_value,
MIN(created_at) as first_order_date,
MAX(created_at) as last_order_date
FROM orders
WHERE status = 'completed'
GROUP BY user_id
;;
# 持久化策略
datagroup_trigger: daily_refresh
distribution_style: all
sortkeys: ["user_id"]
indexes: ["user_id"]
}
dimension: user_id {
primary_key: yes
type: number
sql: ${TABLE}.user_id ;;
}
dimension: lifetime_orders {
type: number
sql: ${TABLE}.lifetime_orders ;;
}
measure: total_lifetime_value {
type: sum
sql: ${lifetime_value} ;;
value_format_name: usd
}
}
增量 PDT:
view: daily_order_summary {
derived_table: {
sql:
SELECT
DATE(created_at) as order_date,
status,
COUNT(*) as order_count,
SUM(total_amount) as total_revenue
FROM orders
WHERE
{% condition order_date %} DATE(created_at) {% endcondition %}
GROUP BY 1, 2
;;
# 增量策略
datagroup_trigger: hourly_refresh
increment_key: "order_date"
increment_offset: 3
# 用于增量加载的 SQL
sql_trigger_value: SELECT CURRENT_DATE ;;
partition_keys: ["order_date"]
}
dimension_group: order {
type: time
timeframes: [date, week, month]
sql: ${TABLE}.order_date ;;
}
filter: order_date {
type: date
}
}
原生派生表:
explore: orders {
# 内联派生表
join: order_summary {
type: left_outer
sql_on: ${orders.id} = ${order_summary.order_id} ;;
relationship: one_to_one
sql_table_name:
(SELECT
order_id,
COUNT(*) as item_count,
SUM(quantity) as total_quantity
FROM order_items
GROUP BY order_id)
;;
}
}
高级关联模式:
explore: orders {
# 多对一关联
join: users {
type: left_outer
sql_on: ${orders.user_id} = ${users.id} ;;
relationship: many_to_one
}
# 使用对称聚合的一对多关联
join: order_items {
type: left_outer
sql_on: ${orders.id} = ${order_items.order_id} ;;
relationship: one_to_many
}
# 防止多对一扇出
join: products {
type: left_outer
sql_on: ${order_items.product_id} = ${products.id} ;;
relationship: many_to_one
required_joins: [order_items]
}
# 基于派生表的关联
join: customer_metrics {
type: left_outer
sql_on: ${users.id} = ${customer_metrics.user_id} ;;
relationship: one_to_one
}
# 交叉关联(谨慎使用)
join: date_spine {
type: cross
relationship: many_to_many
}
# 包含额外条件的关联
join: user_preferences {
type: left_outer
sql_on: ${users.id} = ${user_preferences.user_id}
AND ${user_preferences.is_active} = true ;;
relationship: one_to_one
}
}
优化:
# 扩展基础探索
explore: +orders {
label: "订单扩展"
# 添加额外关联
join: promotions {
type: left_outer
sql_on: ${orders.promotion_id} = ${promotions.id} ;;
relationship: many_to_one
}
# 覆盖现有关联
join: users {
fields: [users.id, users.name, users.email] # 限制字段
}
}
参数:
view: orders {
# 用于动态度量的参数
parameter: metric_selector {
type: unquoted
allowed_value: {
label: "收入"
value: "revenue"
}
allowed_value: {
label: "订单数量"
value: "count"
}
allowed_value: {
label: "平均订单价值"
value: "aov"
}
}
measure: dynamic_metric {
label_from_parameter: metric_selector
type: number
sql:
{% if metric_selector._parameter_value == 'revenue' %}
${total_revenue}
{% elsif metric_selector._parameter_value == 'count' %}
${count}
{% elsif metric_selector._parameter_value == 'aov' %}
${average_order_value}
{% else %}
NULL
{% endif %}
;;
}
# 日期范围参数
parameter: timeframe_picker {
type: unquoted
allowed_value: {
label: "日"
value: "date"
}
allowed_value: {
label: "周"
value: "week"
}
allowed_value: {
label: "月"
value: "month"
}
}
dimension: dynamic_timeframe {
label_from_parameter: timeframe_picker
type: string
sql:
{% if timeframe_picker._parameter_value == 'date' %}
${created_date}
{% elsif timeframe_picker._parameter_value == 'week' %}
${created_week}
{% elsif timeframe_picker._parameter_value == 'month' %}
${created_month}
{% else %}
${created_date}
{% endif %}
;;
}
}
模板化过滤器:
view: orders {
# 仅过滤器字段
filter: date_filter {
type: date
description: "使用此过滤器定义日期范围"
}
# 使用过滤器的维度
dimension: is_in_date_range {
type: yesno
sql: {% condition date_filter %} ${created_raw} {% endcondition %} ;;
}
# 使用过滤器的度量
measure: orders_in_range {
type: count
filters: [is_in_date_range: "yes"]
}
# 多过滤器条件
filter: amount_range {
type: number
}
measure: orders_in_amount_range {
type: count
sql: ${id} ;;
filters: [
status: "completed"
]
sql: {% condition amount_range %} ${total_amount} {% endcondition %} ;;
}
}
仪表板定义:
# dashboards/executive_overview.dashboard.lookml
- dashboard: executive_overview
title: 执行概览
layout: newspaper
preferred_viewer: dashboards-next
filters:
- name: date_range
title: 日期范围
type: field_filter
default_value: 最近 30 天
allow_multiple_values: true
required: false
model: analytics
explore: orders
field: orders.created_date
- name: region
title: 区域
type: field_filter
default_value: ""
allow_multiple_values: true
required: false
model: analytics
explore: orders
field: users.region
elements:
# 收入磁贴
- name: total_revenue
title: 总收入
model: analytics
explore: orders
type: single_value
fields: [orders.total_revenue]
filters:
orders.status: completed
sorts: [orders.total_revenue desc]
limit: 500
listen:
date_range: orders.created_date
region: users.region
row: 0
col: 0
width: 6
height: 4
# 订单数量磁贴
- name: order_count
title: 总订单数
model: analytics
explore: orders
type: single_value
fields: [orders.count]
listen:
date_range: orders.created_date
region: users.region
row: 0
col: 6
width: 6
height: 4
# 收入趋势图表
- name: revenue_trend
title: 收入趋势
model: analytics
explore: orders
type: looker_line
fields: [orders.created_date, orders.total_revenue, orders.count]
fill_fields: [orders.created_date]
sorts: [orders.created_date desc]
limit: 500
x_axis_gridlines: false
y_axis_gridlines: true
show_view_names: false
show_y_axis_labels: true
show_y_axis_ticks: true
y_axis_tick_density: default
y_axis_tick_density_custom: 5
show_x_axis_label: true
show_x_axis_ticks: true
y_axis_scale_mode: linear
x_axis_reversed: false
y_axis_reversed: false
plot_size_by_field: false
trellis: ''
stacking: ''
limit_displayed_rows: false
legend_position: center
point_style: none
show_value_labels: false
label_density: 25
x_axis_scale: auto
y_axis_combined: true
show_null_points: true
interpolation: linear
y_axes: [{label: 收入, orientation: left, series: [{axisId: orders.total_revenue,
id: orders.total_revenue, name: 总收入}], showLabels: true, showValues: true,
unpinAxis: false, tickDensity: default, tickDensityCustom: 5, type: linear}]
series_colors:
orders.total_revenue: "#1f77b4"
listen:
date_range: orders.created_date
region: users.region
row: 4
col: 0
width: 12
height: 6
# 热门产品表格
- name: top_products
title: 热门产品
model: analytics
explore: orders
type: looker_grid
fields: [products.name, order_items.total_quantity, order_items.total_revenue]
sorts: [order_items.total_revenue desc]
limit: 10
show_view_names: false
show_row_numbers: true
transpose: false
truncate_text: true
hide_totals: false
hide_row_totals: false
size_to_fit: true
table_theme: white
limit_displayed_rows: false
enable_conditional_formatting: true
header_text_alignment: left
header_font_size: '12'
rows_font_size: '12'
conditional_formatting: [{type: along a scale..., value: !!null '', background_color: !!null '',
font_color: !!null '', color_application: {collection_id: default, palette_id: default-sequential-0},
bold: false, italic: false, strikethrough: false, fields: [order_items.total_revenue]}]
listen:
date_range: orders.created_date
region: users.region
row: 10
col: 0
width: 12
height: 6
用户属性:
# 基于用户属性的访问过滤器
explore: orders {
access_filter: {
field: users.country
user_attribute: country
}
access_filter: {
field: users.region
user_attribute: user_region
}
# 使用用户属性的 SQL 始终过滤条件
sql_always_where:
{% if _user_attributes['department'] == 'finance' %}
${orders.status} = 'completed'
{% else %}
1=1
{% endif %}
;;
}
字段级安全:
view: users {
dimension: email {
type: string
sql: ${TABLE}.email ;;
# 对非管理员用户隐藏
required_access_grants: [admin_only]
}
dimension: ssn {
type: string
sql: ${TABLE}.ssn ;;
# 多个必需的授权(AND 逻辑)
required_access_grants: [admin_only, pii_access]
}
}
# 定义访问授权
access_grant: admin_only {
user_attribute: role
allowed_values: ["admin", "super_admin"]
}
access_grant: pii_access {
user_attribute: can_see_pii
allowed_values: ["yes"]
}
value_format_name 实现一致的格式化drill_fields 定义探索路径sql_always_where 进行数据过滤always_filter 默认值extends 创建可重用的维度# 错误:不正确的扇出处理
measure: total_items {
type: sum
sql: ${order_items.quantity} ;; # 在一对多关联中会重复计数
}
# 正确:使用对称聚合或子查询
measure: total_items {
type: sum_distinct
sql_distinct_key: ${order_items.id} ;;
sql: ${order_items.quantity} ;;
}
# 错误:没有主键
view: users {
dimension: id { type: number }
}
# 正确:定义主键
view: users {
dimension: id {
primary_key: yes
type: number
}
}
# 错误:硬编码逻辑
dimension: is_current_year {
sql: YEAR(${created_date}) = 2024 ;;
}
# 正确:动态逻辑
dimension: is_current_year {
sql: YEAR(${created_date}) = YEAR(CURRENT_DATE) ;;
}
# 错误:没有文档
dimension: ltv { type: number sql: ${TABLE}.ltv ;; }
# 正确:清晰的文档
dimension: ltv {
type: number
sql: ${TABLE}.ltv ;;
label: "生命周期价值"
description: "客户在所有时间内的总收入"
value_format_name: usd
}
每周安装次数
57
仓库
GitHub 星标数
12
首次出现
2026年1月24日
安全审计
安装于
opencode49
codex48
gemini-cli45
github-copilot43
cursor42
kimi-cli40
You are an expert in Looker with deep knowledge of LookML, explores, dimensions, measures, dashboards, PDTs (Persistent Derived Tables), and semantic data modeling. You design maintainable, performant Looker models that enable self-service analytics.
View Definition:
# views/orders.view.lkml
view: orders {
sql_table_name: public.orders ;;
drill_fields: [id]
# Primary key
dimension: id {
primary_key: yes
type: number
sql: ${TABLE}.id ;;
}
# Foreign key
dimension: user_id {
type: number
hidden: yes
sql: ${TABLE}.user_id ;;
}
# Dimensions
dimension: status {
type: string
sql: ${TABLE}.status ;;
description: "Order status (pending, completed, cancelled, refunded)"
}
dimension: total_amount {
type: number
sql: ${TABLE}.total_amount ;;
value_format_name: usd
description: "Total order amount including tax and shipping"
}
# Date dimensions
dimension_group: created {
type: time
timeframes: [
raw,
time,
date,
week,
month,
quarter,
year
]
sql: ${TABLE}.created_at ;;
description: "When the order was created"
}
dimension_group: completed {
type: time
timeframes: [date, week, month]
sql: ${TABLE}.completed_at ;;
convert_tz: no
datatype: date
}
# Measures
measure: count {
type: count
drill_fields: [detail*]
}
measure: total_revenue {
type: sum
sql: ${total_amount} ;;
value_format_name: usd
description: "Sum of all order amounts"
}
measure: average_order_value {
type: average
sql: ${total_amount} ;;
value_format_name: usd
description: "Average order amount"
}
measure: completed_orders {
type: count
filters: [status: "completed"]
description: "Count of completed orders"
}
# Sets for drilling
set: detail {
fields: [
id,
users.name,
created_date,
status,
total_amount
]
}
}
Model Definition:
# models/analytics.model.lkml
connection: "production_database"
include: "/views/**/*.view.lkml"
include: "/dashboards/**/*.dashboard.lookml"
# Datagroups for caching
datagroup: daily_refresh {
sql_trigger: SELECT CURRENT_DATE ;;
max_cache_age: "24 hours"
}
datagroup: hourly_refresh {
sql_trigger: SELECT FLOOR(EXTRACT(EPOCH FROM CURRENT_TIMESTAMP) / 3600) ;;
max_cache_age: "1 hour"
}
# Explores
explore: orders {
label: "Orders"
description: "Order transactions and related data"
# Joins
join: users {
type: left_outer
sql_on: ${orders.user_id} = ${users.id} ;;
relationship: many_to_one
}
join: order_items {
type: left_outer
sql_on: ${orders.id} = ${order_items.order_id} ;;
relationship: one_to_many
}
join: products {
type: left_outer
sql_on: ${order_items.product_id} = ${products.id} ;;
relationship: many_to_one
}
# Filters
sql_always_where: ${orders.created_date} >= '2020-01-01' ;;
always_filter: {
filters: [orders.created_date: "last 90 days"]
}
# Access control
access_filter: {
field: users.country
user_attribute: country
}
}
explore: users {
label: "Customers"
join: orders {
type: left_outer
sql_on: ${users.id} = ${orders.user_id} ;;
relationship: one_to_many
}
# Aggregate awareness
aggregate_table: rollup__created_month__count {
query: {
dimensions: [created_month]
measures: [count]
}
materialization: {
datagroup_trigger: daily_refresh
}
}
}
Derived Dimensions:
view: users {
# Concatenation
dimension: full_name {
type: string
sql: CONCAT(${first_name}, ' ', ${last_name}) ;;
}
# Case statement
dimension: customer_segment {
type: string
sql: CASE
WHEN ${lifetime_value} >= 10000 THEN 'VIP'
WHEN ${lifetime_value} >= 5000 THEN 'High Value'
WHEN ${lifetime_value} >= 1000 THEN 'Medium Value'
ELSE 'Low Value'
END ;;
}
# Boolean dimension
dimension: is_high_value {
type: yesno
sql: ${lifetime_value} >= 5000 ;;
}
# Duration calculation
dimension: days_since_signup {
type: number
sql: DATEDIFF(day, ${created_date}, CURRENT_DATE) ;;
}
# Tier dimension
dimension: age_tier {
type: tier
tiers: [18, 25, 35, 45, 55, 65]
style: integer
sql: ${age} ;;
}
# Yesno with complex logic
dimension: is_active_customer {
type: yesno
sql: ${last_order_date} >= DATEADD(day, -90, CURRENT_DATE)
AND ${is_deleted} = false ;;
}
}
Advanced Measures:
view: orders {
# Conditional measures
measure: high_value_orders {
type: count
filters: [total_amount: ">100"]
}
measure: revenue_high_value_orders {
type: sum
sql: ${total_amount} ;;
filters: [total_amount: ">100"]
value_format_name: usd
}
# Distinct count
measure: unique_customers {
type: count_distinct
sql: ${user_id} ;;
description: "Number of unique customers"
}
# Percentile
measure: median_order_value {
type: median
sql: ${total_amount} ;;
value_format_name: usd
}
measure: p95_order_value {
type: percentile
percentile: 95
sql: ${total_amount} ;;
value_format_name: usd
}
# Running total (table calculation alternative)
measure: cumulative_revenue {
type: running_total
sql: ${total_revenue} ;;
value_format_name: usd
}
# Filtered measure with OR logic
measure: orders_pending_or_processing {
type: count
filters: [
status: "pending,processing"
]
}
# Ratio measure
measure: conversion_rate {
type: number
sql: 1.0 * ${completed_orders} / NULLIF(${count}, 0) ;;
value_format_name: percent_2
}
# Average distinct (for distinct key values)
measure: avg_daily_orders {
type: average_distinct
sql: ${count} ;;
sql_distinct_key: ${created_date} ;;
}
}
SQL-Based PDTs:
view: customer_lifetime_metrics {
derived_table: {
sql:
SELECT
user_id,
COUNT(*) as lifetime_orders,
SUM(total_amount) as lifetime_value,
AVG(total_amount) as avg_order_value,
MIN(created_at) as first_order_date,
MAX(created_at) as last_order_date
FROM orders
WHERE status = 'completed'
GROUP BY user_id
;;
# Persistence strategy
datagroup_trigger: daily_refresh
distribution_style: all
sortkeys: ["user_id"]
indexes: ["user_id"]
}
dimension: user_id {
primary_key: yes
type: number
sql: ${TABLE}.user_id ;;
}
dimension: lifetime_orders {
type: number
sql: ${TABLE}.lifetime_orders ;;
}
measure: total_lifetime_value {
type: sum
sql: ${lifetime_value} ;;
value_format_name: usd
}
}
Incremental PDTs:
view: daily_order_summary {
derived_table: {
sql:
SELECT
DATE(created_at) as order_date,
status,
COUNT(*) as order_count,
SUM(total_amount) as total_revenue
FROM orders
WHERE
{% condition order_date %} DATE(created_at) {% endcondition %}
GROUP BY 1, 2
;;
# Incremental strategy
datagroup_trigger: hourly_refresh
increment_key: "order_date"
increment_offset: 3
# SQL for incremental loads
sql_trigger_value: SELECT CURRENT_DATE ;;
partition_keys: ["order_date"]
}
dimension_group: order {
type: time
timeframes: [date, week, month]
sql: ${TABLE}.order_date ;;
}
filter: order_date {
type: date
}
}
Native Derived Tables (NDTs):
explore: orders {
# Inline derived table
join: order_summary {
type: left_outer
sql_on: ${orders.id} = ${order_summary.order_id} ;;
relationship: one_to_one
sql_table_name:
(SELECT
order_id,
COUNT(*) as item_count,
SUM(quantity) as total_quantity
FROM order_items
GROUP BY order_id)
;;
}
}
Advanced Join Patterns:
explore: orders {
# Many-to-one join
join: users {
type: left_outer
sql_on: ${orders.user_id} = ${users.id} ;;
relationship: many_to_one
}
# One-to-many join with symmetric aggregates
join: order_items {
type: left_outer
sql_on: ${orders.id} = ${order_items.order_id} ;;
relationship: one_to_many
}
# Many-to-one fanout prevention
join: products {
type: left_outer
sql_on: ${order_items.product_id} = ${products.id} ;;
relationship: many_to_one
required_joins: [order_items]
}
# Join based on derived table
join: customer_metrics {
type: left_outer
sql_on: ${users.id} = ${customer_metrics.user_id} ;;
relationship: one_to_one
}
# Cross join (use sparingly)
join: date_spine {
type: cross
relationship: many_to_many
}
# Join with additional conditions
join: user_preferences {
type: left_outer
sql_on: ${users.id} = ${user_preferences.user_id}
AND ${user_preferences.is_active} = true ;;
relationship: one_to_one
}
}
Refinements:
# Extend base explore
explore: +orders {
label: "Orders Extended"
# Add additional join
join: promotions {
type: left_outer
sql_on: ${orders.promotion_id} = ${promotions.id} ;;
relationship: many_to_one
}
# Override existing join
join: users {
fields: [users.id, users.name, users.email] # Limit fields
}
}
Parameters:
view: orders {
# Parameter for dynamic measures
parameter: metric_selector {
type: unquoted
allowed_value: {
label: "Revenue"
value: "revenue"
}
allowed_value: {
label: "Order Count"
value: "count"
}
allowed_value: {
label: "Average Order Value"
value: "aov"
}
}
measure: dynamic_metric {
label_from_parameter: metric_selector
type: number
sql:
{% if metric_selector._parameter_value == 'revenue' %}
${total_revenue}
{% elsif metric_selector._parameter_value == 'count' %}
${count}
{% elsif metric_selector._parameter_value == 'aov' %}
${average_order_value}
{% else %}
NULL
{% endif %}
;;
}
# Date range parameter
parameter: timeframe_picker {
type: unquoted
allowed_value: {
label: "Day"
value: "date"
}
allowed_value: {
label: "Week"
value: "week"
}
allowed_value: {
label: "Month"
value: "month"
}
}
dimension: dynamic_timeframe {
label_from_parameter: timeframe_picker
type: string
sql:
{% if timeframe_picker._parameter_value == 'date' %}
${created_date}
{% elsif timeframe_picker._parameter_value == 'week' %}
${created_week}
{% elsif timeframe_picker._parameter_value == 'month' %}
${created_month}
{% else %}
${created_date}
{% endif %}
;;
}
}
Templated Filters:
view: orders {
# Filter-only field
filter: date_filter {
type: date
description: "Use this filter to define date range"
}
# Dimension using filter
dimension: is_in_date_range {
type: yesno
sql: {% condition date_filter %} ${created_raw} {% endcondition %} ;;
}
# Measure using filter
measure: orders_in_range {
type: count
filters: [is_in_date_range: "yes"]
}
# Multiple filter conditions
filter: amount_range {
type: number
}
measure: orders_in_amount_range {
type: count
sql: ${id} ;;
filters: [
status: "completed"
]
sql: {% condition amount_range %} ${total_amount} {% endcondition %} ;;
}
}
Dashboard Definition:
# dashboards/executive_overview.dashboard.lookml
- dashboard: executive_overview
title: Executive Overview
layout: newspaper
preferred_viewer: dashboards-next
filters:
- name: date_range
title: Date Range
type: field_filter
default_value: last 30 days
allow_multiple_values: true
required: false
model: analytics
explore: orders
field: orders.created_date
- name: region
title: Region
type: field_filter
default_value: ""
allow_multiple_values: true
required: false
model: analytics
explore: orders
field: users.region
elements:
# Revenue tile
- name: total_revenue
title: Total Revenue
model: analytics
explore: orders
type: single_value
fields: [orders.total_revenue]
filters:
orders.status: completed
sorts: [orders.total_revenue desc]
limit: 500
listen:
date_range: orders.created_date
region: users.region
row: 0
col: 0
width: 6
height: 4
# Order count tile
- name: order_count
title: Total Orders
model: analytics
explore: orders
type: single_value
fields: [orders.count]
listen:
date_range: orders.created_date
region: users.region
row: 0
col: 6
width: 6
height: 4
# Revenue trend chart
- name: revenue_trend
title: Revenue Trend
model: analytics
explore: orders
type: looker_line
fields: [orders.created_date, orders.total_revenue, orders.count]
fill_fields: [orders.created_date]
sorts: [orders.created_date desc]
limit: 500
x_axis_gridlines: false
y_axis_gridlines: true
show_view_names: false
show_y_axis_labels: true
show_y_axis_ticks: true
y_axis_tick_density: default
y_axis_tick_density_custom: 5
show_x_axis_label: true
show_x_axis_ticks: true
y_axis_scale_mode: linear
x_axis_reversed: false
y_axis_reversed: false
plot_size_by_field: false
trellis: ''
stacking: ''
limit_displayed_rows: false
legend_position: center
point_style: none
show_value_labels: false
label_density: 25
x_axis_scale: auto
y_axis_combined: true
show_null_points: true
interpolation: linear
y_axes: [{label: Revenue, orientation: left, series: [{axisId: orders.total_revenue,
id: orders.total_revenue, name: Total Revenue}], showLabels: true, showValues: true,
unpinAxis: false, tickDensity: default, tickDensityCustom: 5, type: linear}]
series_colors:
orders.total_revenue: "#1f77b4"
listen:
date_range: orders.created_date
region: users.region
row: 4
col: 0
width: 12
height: 6
# Top products table
- name: top_products
title: Top Products
model: analytics
explore: orders
type: looker_grid
fields: [products.name, order_items.total_quantity, order_items.total_revenue]
sorts: [order_items.total_revenue desc]
limit: 10
show_view_names: false
show_row_numbers: true
transpose: false
truncate_text: true
hide_totals: false
hide_row_totals: false
size_to_fit: true
table_theme: white
limit_displayed_rows: false
enable_conditional_formatting: true
header_text_alignment: left
header_font_size: '12'
rows_font_size: '12'
conditional_formatting: [{type: along a scale..., value: !!null '', background_color: !!null '',
font_color: !!null '', color_application: {collection_id: default, palette_id: default-sequential-0},
bold: false, italic: false, strikethrough: false, fields: [order_items.total_revenue]}]
listen:
date_range: orders.created_date
region: users.region
row: 10
col: 0
width: 12
height: 6
User Attributes:
# Access filters based on user attributes
explore: orders {
access_filter: {
field: users.country
user_attribute: country
}
access_filter: {
field: users.region
user_attribute: user_region
}
# SQL always where with user attribute
sql_always_where:
{% if _user_attributes['department'] == 'finance' %}
${orders.status} = 'completed'
{% else %}
1=1
{% endif %}
;;
}
Field-Level Security:
view: users {
dimension: email {
type: string
sql: ${TABLE}.email ;;
# Hide from non-admin users
required_access_grants: [admin_only]
}
dimension: ssn {
type: string
sql: ${TABLE}.ssn ;;
# Multiple required grants (AND logic)
required_access_grants: [admin_only, pii_access]
}
}
# Define access grants
access_grant: admin_only {
user_attribute: role
allowed_values: ["admin", "super_admin"]
}
access_grant: pii_access {
user_attribute: can_see_pii
allowed_values: ["yes"]
}
# Bad: Incorrect fanout handling
measure: total_items {
type: sum
sql: ${order_items.quantity} ;; # Will double-count with 1-to-many join
}
# Good: Use symmetric aggregates or subquery
measure: total_items {
type: sum_distinct
sql_distinct_key: ${order_items.id} ;;
sql: ${order_items.quantity} ;;
}
# Bad: No primary key
view: users {
dimension: id { type: number }
}
# Good: Define primary key
view: users {
dimension: id {
primary_key: yes
type: number
}
}
# Bad: Hardcoded logic
dimension: is_current_year {
sql: YEAR(${created_date}) = 2024 ;;
}
# Good: Dynamic logic
dimension: is_current_year {
sql: YEAR(${created_date}) = YEAR(CURRENT_DATE) ;;
}
# Bad: No documentation
dimension: ltv { type: number sql: ${TABLE}.ltv ;; }
# Good: Clear documentation
dimension: ltv {
type: number
sql: ${TABLE}.ltv ;;
label: "Lifetime Value"
description: "Total revenue from customer over all time"
value_format_name: usd
}
Weekly Installs
57
Repository
GitHub Stars
12
First Seen
Jan 24, 2026
Security Audits
Gen Agent Trust HubFailSocketPassSnykPass
Installed on
opencode49
codex48
gemini-cli45
github-copilot43
cursor42
kimi-cli40
DOCX文件创建、编辑与分析完整指南 - 使用docx-js、Pandoc和Python脚本
55,800 周安装