> ## 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.

# Transpose Rows

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 **Transpose Rows** transformation component lets you combine multiple input rows into a single output row. One row will be produced for each value of the columns specified in the **Groupings** parameter. This is especially helpful when you want to restructure long datasets into a wide format for reporting, comparisons, or aggregations.

The output of this component differs slightly depending on your cloud data warehouse environment:

* In a Snowflake environment, this component concatenates each value into a delimited string with the format `[ value, value, value ]`. You could then use a [Split Field](/docs/components/split-field) component after the Transpose Rows component to convert the delimited strings into a set of new columns, if required.
* In a Databricks environment, this component returns values as Databricks `ARRAY <String>` types. These values can't be manipulated by a Split Field component.
* In Amazon Redshift and Google BigQuery environments, this component concatenates each value into a delimited string with the format `value,value,value`. You could then use a [Split Field](/docs/components/split-field) component after the Transpose Rows component to convert the delimited strings into a set of new columns, if required.

<Note>
  - For an alternative approach to transforming rows into columns, consider the [Pivot](/docs/components/pivot) component instead.
  - If you want to map columns from the input dataset into rows in the output data, use the [Transpose Columns](/docs/components/transpose-columns) component.
</Note>

### Use case

This component can be used to restructure long datasets into a wide format for reporting, comparisons, or aggregations. Some typical uses of this are:

* Pivoting long-form time-based data into a wide format for period-over-period comparisons.
* Condensing repeated rows (for example, in survey responses or log files) into a single record.

***

## Properties

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

    {/* <!-- param-start:[aggregations] | warehouses: [snowflake] --> */}

    <ResponseField name="Aggregations" type="dual listbox" required>
      The input column to aggregate.

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

    {/* <!-- param-start:[sortOrder] | warehouses: [snowflake] --> */}

    <ResponseField name="Sort order" type="dual listbox">
      Rows included in the "groupings" are ordered using this **Sort order** parameter. If you're performing multiple transpositions, ordering will ensure that the items are in a consistent order.

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

    {/* <!-- param-start:[groupings] | warehouses: [snowflake] --> */}

    <ResponseField name="Groupings" type="dual listbox">
      One or more source columns that form the groupings. The output will have one row for every combination of grouping column values.

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

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

    {/* <!-- param-start:[aggregations] | warehouses: [databricks] --> */}

    <ResponseField name="Aggregations" type="dual listbox" required>
      The input column to aggregate.

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

    {/* <!-- param-start:[sortOrder] | warehouses: [databricks] --> */}

    <ResponseField name="Sort order" type="dual listbox">
      Rows included in the "groupings" are ordered using this **Sort order** parameter. If you're performing multiple transpositions, ordering will ensure that the items are in a consistent order.

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

    {/* <!-- param-start:[groupings] | warehouses: [databricks] --> */}

    <ResponseField name="Groupings" type="dual listbox">
      One or more source columns that form the groupings. The output will have one row for every combination of grouping column values.

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

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

    {/* <!-- param-start:[aggregations] | warehouses: [redshift] --> */}

    <ResponseField name="Aggregations" type="dual listbox" required>
      The input column to aggregate.

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

    {/* <!-- param-start:[sortOrder] | warehouses: [redshift] --> */}

    <ResponseField name="Sort order" type="dual listbox">
      Rows included in the "groupings" are ordered using this **Sort order** parameter. If you're performing multiple transpositions, ordering will ensure that the items are in a consistent order.

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

    {/* <!-- param-start:[groupings] | warehouses: [redshift] --> */}

    <ResponseField name="Groupings" type="dual listbox">
      One or more source columns that form the groupings. The output will have one row for every combination of grouping column values.

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

    {/* <!-- param-start:[delimiter] | warehouses: [redshift] --> */}

    <ResponseField name="Delimiter" type="string" required>
      A delimiting character used to separate concatenated values. The default is a comma.
    </ResponseField>

    {/* <!-- param-start:[nullReplace] | warehouses: [redshift] --> */}

    <ResponseField name="Null replace" type="column editor">
      * **Field:** Select a field from the drop-down menu. This field will have any NULL values replaced by a value the user specifies in the "Replacement" column of this parameter. This may be useful for retaining the order of elements, since otherwise NULL values will not be included.
      * **Replacement:** The value used to replace NULL values in the corresponding field (row).

      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:[distinctAggregations] | warehouses: [redshift] --> */}

    <ResponseField name="Distinct aggregations" type="boolean" required>
      When "Yes", any duplicates from the selected aggregation columns are removed. Default setting is "No".
    </ResponseField>
  </Tab>

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

    {/* <!-- param-start:[aggregations] | warehouses: [bigquery] --> */}

    <ResponseField name="Aggregations" type="dual listbox" required>
      The input column to aggregate.

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

    {/* <!-- param-start:[sortOrder] | warehouses: [bigquery] --> */}

    <ResponseField name="Sort order" type="dual listbox">
      Rows included in the "groupings" are ordered using this **Sort order** parameter. If you're performing multiple transpositions, ordering will ensure that the items are in a consistent order.

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

    {/* <!-- param-start:[groupings] | warehouses: [bigquery] --> */}

    <ResponseField name="Groupings" type="dual listbox">
      One or more source columns that form the groupings. The output will have one row for every combination of grouping column values.

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

    {/* <!-- param-start:[delimiter] | warehouses: [bigquery] --> */}

    <ResponseField name="Delimiter" type="string" required>
      A delimiting character used to separate concatenated values. The default is a comma.
    </ResponseField>

    {/* <!-- param-start:[nullReplace] | warehouses: [bigquery] --> */}

    <ResponseField name="Null replace" type="column editor">
      * **Field:** Select a field from the drop-down menu. This field will have any NULL values replaced by a value the user specifies in the "Replacement" column of this parameter. This may be useful for retaining the order of elements, since otherwise NULL values will not be included.
      * **Replacement:** The value used to replace NULL values in the corresponding field (row).

      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>
  </Tab>
</Tabs>

## Example

<Note>
  This example uses a Snowflake project. Other cloud data warehouses will give slightly different output formats.
</Note>

We have a table of products and yearly sales information. However, the format gives us a lot of repeated data:

```
Input Data

+------------+------+---------+
| product_id | year | sales   |
+------------+------+---------+
| P123       | 2023 | 1000.00 |
| P124       | 2023 | 2500.00 |
| P125       | 2023 | 1800.00 |
| P126       | 2023 | 3500.00 |
| P123       | 2024 | 1500.00 |
| P124       | 2024 | 3000.00 |
| P125       | 2024 | 2200.00 |
| P126       | 2024 | 4000.00 |
+------------+------+---------+
```

We want to transpose the data into a condensed format that puts the data for each product into a single row:

```
Output Data

+------------+--------------------+----------------+
| product_id | year               | sales          |
+------------+--------------------+----------------+
| P126       | [ "2023", "2024" ] | [ 3500, 4000 ] |
| P123       | [ "2023", "2024" ] | [ 1000, 1500 ] |
| P124       | [ "2023", "2024" ] | [ 2500, 3000 ] |
| P125       | [ "2023", "2024" ] | [ 1800, 2200 ] |
+------------+--------------------+----------------+
```

To achieve this transformation, we connect the input table to a Transpose Rows component, which we will configure as follows:

* **Aggregations:** year, sales
* **Sort Order:** Left **blank**. In a long dataset, sorting on product\_id might be appropriate.
* **Groupings:** product\_id
