# Help: `inline_columns` (concept)

`INLINE_COLUMNS` creates a small data table directly in FeatureQL, without any external SQL source. Use it for lookup tables, test data, and scenario parameters.

## CSV format — multiline, header on first line

```featureql
RATES := INLINE_COLUMNS(
    currency  VARCHAR,
    rate      DOUBLE
    FROM CSV(
        currency,rate
        USD,1.0
        EUR,1.08
        GBP,1.27
    )
),
```

Runnable snippet: [`help_inline_csv`](/llms/help_inline_csv.md)

## With entity binding — for RELATED lookups

```featureql
SCENARIOS   := ENTITY(),
SCENARIO_ID := INPUT(BIGINT#SCENARIOS),
PARAMS := INLINE_COLUMNS(
    scenario_id BIGINT#SCENARIOS BIND TO SCENARIO_ID,
    churn_rate  DOUBLE,
    growth_rate DOUBLE
    FROM CSV(
        scenario_id,churn_rate,growth_rate
        1,0.02,0.05
        2,0.03,0.08
        3,0.01,0.03
    )
),
CHURN  := SCENARIO_ID.RELATED(PARAMS[churn_rate]),
GROWTH := SCENARIO_ID.RELATED(PARAMS[growth_rate]),
```

Runnable snippet: [`help_inline_columns_related`](/llms/help_inline_columns_related.md)

## JSON alternative — avoids newline sensitivity

```featureql
FROM JSON([{"currency": "USD", "rate": 1.0}, {"currency": "EUR", "rate": 1.08}])
```

Runnable snippet: [`help_inline_json`](/llms/help_inline_json.md)

## ⚠ CSV must use real line breaks — not single-line

```featureql
-- WRONG: all on one line — the parser sees a header with no data rows
FROM CSV(currency,rate,USD,1.0,EUR,1.08)

-- RIGHT: each row on its own line
FROM CSV(
    currency,rate
    USD,1.0
    EUR,1.08
)
```

# Help: `inline_columns` (snippet)

## `help_inline_csv`

```slt
# tags: inline_columns, inline_csv, from_csv
# schema: VARCHAR#CURRENCIES|DOUBLE
query CURRENCY:V,RATE:D rowsort
DEFINE
    currencies := ENTITY(),
    currency := INPUT(VARCHAR#currencies),
    rates := INLINE_COLUMNS(
        currency VARCHAR#currencies BIND TO currency,
        rate DOUBLE
        FROM CSV(
            currency,rate
            USD,1.0
            EUR,1.08
            GBP,1.27
        )
    ),
    rate := rates[rate]
RETURN
    currency,
    rate
FOR
    currency := BIND_VALUES(ARRAY('EUR', 'GBP'))
;
----
EUR	1.08
GBP	1.27
```

## `help_inline_columns_related`

```slt
# tags: inline_columns, external_columns, related
# schema: BIGINT#SCENARIOS|DOUBLE|DOUBLE
query SCENARIO_ID:I,CHURN:D,GROWTH:D rowsort
DEFINE
    scenarios := ENTITY(),
    scenario_id := INPUT(BIGINT#scenarios),
    params := INLINE_COLUMNS(
        scenario_id BIGINT#scenarios BIND TO scenario_id,
        churn_rate DOUBLE,
        growth_rate DOUBLE
        FROM CSV(
            scenario_id,churn_rate,growth_rate
            1,0.02,0.05
            2,0.03,0.08
            3,0.01,0.03
        )
    ),
    churn := scenario_id.RELATED(params[churn_rate]),
    growth := scenario_id.RELATED(params[growth_rate])
RETURN
    scenario_id,
    churn,
    growth
FOR
    scenario_id := BIND_VALUES(ARRAY(1, 2, 3))
;
----
1	0.02	0.05
2	0.03	0.08
3	0.01	0.03
```

## `help_inline_json`

```slt
# tags: inline_columns, from_json, mock_data
# schema: BIGINT#CUSTOMERS|VARCHAR
query CUSTOMER_ID:I,CUSTOMER_NAME:V rowsort
DEFINE
    customers := ENTITY(),
    customer_id := INPUT(BIGINT#customers),
    dim := INLINE_COLUMNS(
        customer_id BIGINT#customers BIND TO customer_id,
        name VARCHAR
        FROM JSON([
            {"customer_id": 101, "name": "Alice"},
            {"customer_id": 102, "name": "Bob"}
        ])
    ),
    customer_name := dim[name]
RETURN
    customer_id,
    customer_name
FOR
    customer_id := BIND_VALUES(ARRAY(101, 102))
;
----
101	Alice
102	Bob
```

**Related tags**: [`external_columns`](/llms/external_columns.md) [`from_sql_vs_table`](/llms/entity_model.md) [`pivot`](/llms/pivot.md) [`composite_key`](/llms/composite_key.md)
