```sql
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED       FOLLOWING
VS 
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED       PRECEDING


select product_name, price, group_name, round(avg0), round(avg1)
from (
SELECT
	product_name,
	price,
	group_name,
	avg(price) OVER (PARTITION BY group_name ORDER BY price) avg0,
	avg(price) OVER (PARTITION BY group_name ORDER BY
			price RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) avg1
FROM products INNER JOIN  product_groups USING (group_id)) t
order by group_name, product_name, price;




SELECT
    product_name,
    price,
    group_name,
    round(avg0),
    round(avg1)
FROM
(
    SELECT
        product_name,
        price,
        group_name,
        avg(price) OVER (PARTITION BY group_name ORDER BY price ASC) AS avg0,
        avg(price) OVER (PARTITION BY group_name ORDER BY price ASC RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED PRECEDING) AS avg1
    FROM products
    INNER JOIN product_groups USING (group_id)
) AS t
ORDER BY
    group_name ASC,
    product_name ASC,
    price ASC

```
{
    WriteBufferFromOwnString ostr;
    FormatSettings settings{ostr, true };
    FormatState state;
    FormatStateStacked format_frame;
    formatImpl(settings, state, format_frame);
    return ostr.str();
}
ASTPtr ASTWindowListElement::clone() const
{
    auto result = std::make_shared<ASTWindowListElement>();
    result->name = name;
    result->definition = definition->clone();
    result->children.push_back(result->definition);
    return result;
}
String ASTWindowListElement::getID(char) const
{
    return "WindowListElement";
}
void ASTWindowListElement::formatImpl(const FormatSettings & settings,
    FormatState & state, FormatStateStacked frame) const
{
    settings.ostr << backQuoteIfNeed(name);
    settings.ostr << " AS (";
    definition->formatImpl(settings, state, frame);
    settings.ostr << ")";
}
}