> ## Documentation Index
> Fetch the complete documentation index at: https://docs.maia.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# First/Last

export const ComponentMetadata = ({warehouses, unsupportedWarehouses = [], componentType, connectionInputs, connectionOutputs}) => {
  const allWarehouses = [...warehouses.map(w => ({
    name: w,
    supported: true
  })), ...unsupportedWarehouses.map(w => ({
    name: w,
    supported: false
  }))];
  return <div style={{
    background: 'var(--colors-background-light, #f9fafb)',
    border: '1px solid var(--colors-border-default, #e5e7eb)',
    borderRadius: '12px',
    padding: '20px 28px',
    marginBottom: '28px',
    boxShadow: '0 1px 4px rgba(0,0,0,0.10)'
  }}>
      <table style={{
    width: '100%',
    borderCollapse: 'collapse'
  }}>
        <tbody>
          <tr>
            <td style={{
    fontWeight: '600',
    paddingRight: '32px',
    paddingBottom: '14px',
    whiteSpace: 'nowrap',
    verticalAlign: 'middle',
    width: '180px'
  }}>Project Availability</td>
            <td style={{
    paddingBottom: '14px',
    verticalAlign: 'middle'
  }}>
              <div style={{
    display: 'flex',
    flexWrap: 'wrap',
    gap: '8px'
  }}>
                {allWarehouses.map((w, i) => <span key={i} style={{
    background: w.supported ? '#dcfce7' : '#fee2e2',
    color: w.supported ? '#15803d' : '#b91c1c',
    border: `1px solid ${w.supported ? '#bbf7d0' : '#fca5a5'}`,
    borderRadius: '9999px',
    padding: '3px 12px',
    fontSize: '0.85rem',
    fontWeight: '500',
    whiteSpace: 'nowrap'
  }}>
                    {w.name} {w.supported ? '✅' : '❌'}
                  </span>)}
              </div>
            </td>
          </tr>
          <tr>
            <td style={{
    fontWeight: '600',
    paddingRight: '32px',
    paddingBottom: '14px',
    whiteSpace: 'nowrap',
    verticalAlign: 'middle'
  }}>Component Type</td>
            <td style={{
    paddingBottom: '14px',
    verticalAlign: 'middle'
  }}>{componentType}</td>
          </tr>
          <tr>
            <td style={{
    fontWeight: '600',
    paddingRight: '32px',
    paddingBottom: '14px',
    whiteSpace: 'nowrap',
    verticalAlign: 'middle'
  }}>Connection Inputs</td>
            <td style={{
    paddingBottom: '14px',
    verticalAlign: 'middle'
  }}>{connectionInputs}</td>
          </tr>
          <tr>
            <td style={{
    fontWeight: '600',
    paddingRight: '32px',
    whiteSpace: 'nowrap',
    verticalAlign: 'middle'
  }}>Connection Outputs</td>
            <td style={{
    verticalAlign: 'middle'
  }}>{connectionOutputs}</td>
          </tr>
        </tbody>
      </table>
    </div>;
};

<ComponentMetadata warehouses={["Snowflake", "Databricks", "Amazon Redshift", "Google BigQuery"]} componentType="Transformation" connectionInputs="One" connectionOutputs="Unlimited" />

The **First/Last** transformation component lets you create groups of data, sort these groups, and then return only the first or last row of each group. This component is equivalent to writing a SELECT statement with a window function in-line using the OVER keyword.

For more information, read the following documentation:

| Snowflake                                                                                         | Databricks                                                                                                                 | Amazon Redshift                                                                                                     | Google BigQuery                                                                                                                       |
| ------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| [Snowflake Window functions](https://docs.snowflake.com/en/sql-reference/functions-analytic.html) | [Databricks Window functions](https://docs.databricks.com/en/sql/language-manual/sql-ref-window-functions.html)            | [Amazon Redshift Window functions](https://docs.aws.amazon.com/redshift/latest/dg/c_Window_functions.html)          | [BigQuery Analytic (window) functions](https://docs.cloud.google.com/bigquery/docs/reference/standard-sql/analytic-function-concepts) |
| [Snowflake First Value](https://docs.snowflake.com/en/sql-reference/functions/first_value.html)   | [Databricks Window function First Value](https://docs.databricks.com/en/sql/language-manual/sql-ref-window-functions.html) | [Amazon Redshift Window function First Value](https://docs.aws.amazon.com/redshift/latest/dg/r_WF_first_value.html) | [BigQuery FIRST\_VALUE function](https://docs.cloud.google.com/bigquery/docs/reference/standard-sql/navigation_functions#first_value) |
| [Snowflake Last Value](https://docs.snowflake.com/en/sql-reference/functions/last_value.html)     | [Databricks Window function Last Value](https://docs.databricks.com/en/sql/language-manual/sql-ref-window-functions.html)  | [Amazon Redshift Window function Last Value](https://docs.aws.amazon.com/redshift/latest/dg/r_WF_last_value.html)   | [BigQuery LAST\_VALUE function](https://docs.cloud.google.com/bigquery/docs/reference/standard-sql/navigation_functions#last_value)   |

### Use case

This component can be used to simplify workflows that rely on identifying the start or end points of a time period or sequence of events. For example, you can use it to:

* Group purchase data by customer, sort by purchase date, then use `First` to find the details of each customer's first purchase.
* Group user logins by user, sort by most recent timestamp, then use `Last` to see when your users last logged in.
* Group monthly inventory data by time period, then use two **First/Last** components to view your inventory levels at the start and end of each month.

***

## Properties

<ResponseField name="Name" type="string" required>
  A human-readable name for the component.
</ResponseField>

{/* <!-- param-start:[groupingColumns] | warehouses: [snowflake, databricks, redshift, bigquery] --> */}

<ResponseField name="Grouping columns" type="dual listbox" required>
  Defines how the input data is grouped. This works like an SQL GROUP BY statement. The first or last element of each group will be selected.

  To use grid variables, select the **Use Grid Variable** checkbox at the top of the dialog. For more information, read [Grid variables](/docs/guides/grid-variables).
</ResponseField>

{/* <!-- param-start:[orderingInPartitions] | warehouses: [snowflake, databricks, redshift, bigquery] --> */}

<ResponseField name="Ordering in partitions" type="column editor" required>
  * **Input Column:** The name of the column to use for sorting within the grouped data.
  * **Ordering:** Specify how the selected column is sorted. Options are **Ascending**, **Descending**, **Nulls First**, or **Nulls Last**. For Google BigQuery, only **Ascending** and **Descending** are available.

  Click the **Text mode** toggle at the bottom of the dialog to open a multi-line editor that lets you add items in a single block. For more information, read [Text mode](/docs/guides/components-overview#text-mode).

  To use grid variables, toggle **Use Grid Variable** on at the bottom of the dialog. For more information, read [Grid variables](/docs/guides/grid-variables).
</ResponseField>

{/* <!-- param-start:[firstLastColumns] | warehouses: [snowflake, databricks, redshift, bigquery] --> */}

<ResponseField name="First last columns" type="column editor" required>
  * **Column:** The name of the input column to be passed to the output.
  * **First Last:** Return the First or Last element of the chosen column in the grouped data.

  Click the **Add all** button to automatically populate the **Column** list with all the columns which were *not* selected in the **Grouping columns** property. **First Last** is set to `First` in each row. You can then selectively edit the list if required, but if you click **Add all** again it will return the list to the default fully populated state, removing any changes you have made.

  Click the **Text mode** toggle at the bottom of the dialog to open a multi-line editor that lets you add items in a single block. For more information, read [Text mode](/docs/guides/components-overview#text-mode).

  To use grid variables, toggle **Use Grid Variable** on at the bottom of the dialog. For more information, read [Grid variables](/docs/guides/grid-variables).
</ResponseField>

{/* <!-- param-start:[ignoreNulls] | warehouses: [snowflake, databricks, redshift, bigquery] --> */}

<ResponseField name="Ignore nulls" type="boolean" required>
  Select whether to ignore null values. The default setting is **No** (do not ignore null values).
</ResponseField>
