# Column lineage > A graph of where each output column comes from (through CTEs, joins, UNNEST, views, and pipe stages), built from the SQL as you type. Use it to answer "which table does this number actually come from" without reading the query backwards. Source: https://docs.querylab.io/writing-sql/lineage/ **Query 1** ```sql WITH vehicle_data AS ( SELECT vehicle_sk, make, «hl:model», colour, fuel_type FROM `ace-analytics.warehouse.dim_vehicle` ), make_stats AS ( SELECT make, COUNT(*) AS vehicle_count, COUNT(DISTINCT «hl:model») AS «hl:model_count» FROM vehicle_data GROUP BY make ) SELECT v.vehicle_sk, v.make, v.«hl:model», v.colour, s.vehicle_count, s.«hl:model_count» FROM vehicle_data v JOIN make_stats s USING (make) ``` **Prism Insights → Lineage** TABLE dim_vehicle vehicle_sk make model colour fuel_type CTE vehicle_data vehicle_sk make model colour fuel_type CTE make_stats vehicle_count model_count OUT <output> vehicle_sk make model colour vehicle_count model_count Hovering model_count in the output lights up everything upstream of it: make_stats.model_count, vehicle_data.model, and dim_vehicle.model. ## Opening it Open the Prism Insights panel (header ⋮ → **Prism Insights**, or right-click the editor → **Show Prism Insights**) and choose **Lineage**: a tab when the panel is wide, a dropdown entry when it's narrow. - A project is connected; lineage needs the schema to resolve `SELECT *` and unqualified columns. Without one the view says *Connect to a project to enable lineage analysis*. - The SQL is valid. A partial or broken query shows *Could not analyze lineage for this query*. Nothing has to run. In a multi-statement script it follows the statement selected in the results bar. ## Reading the graph Each box is an object; the badge names its kind: | Badge | Object | | ----------------------------------- | --------------------------------------------------------------------- | | `TABLE`, `VIEW` | A source. Views are expanded, so their own sources appear behind them | | `CTE` | A `WITH` entry | | `SUB`, `DT` | A subquery in `WHERE` / `SELECT`, a derived table in `FROM` | | `TVF`, `UNNEST`, `PIVOT`, `UNPIVOT` | A table function, an array unnest, a pivot | | `OUT`, `DML` | The final output; the target of an `INSERT`, `UPDATE`, `MERGE` | Edges run left to right from source columns to the columns computed from them. A solid edge is a direct input (`v.model` → `model`); a dashed edge is a side input (a `GROUP BY` key, a join condition, a `WHERE` column) that shaped the value without being copied into it. If part of the query couldn't be resolved, the bar above the graph says _Partial result (n errors)_ and draws what it could. ## Moving around the graph - Hover a column to highlight it with everything upstream and downstream; other edges fade. - Scroll to zoom, centered on the pointer. - Drag the background to pan. - Drag a box to move it; edges follow. - Click the zoom badge (bottom right) to toggle fit-to-width and 100%. ## Switching to the table view **Graph | Table** at the right of the summary bar switches to a table with one row per output column: **Output**, **Type**, **Source**, **Transformation**, **Used In**.