SQL Оператор выбора GROUP BY с агрегатной функцией

Следующее больше не является агностиком языка (но это не имеет значения для обсуждения, потому что реализация является легко портативной на другие языки). Я пытался реализовать Luke (theretically лучше всего) решение на императивном языке программирования. Выберите; C# шахты. Не очень изящный вообще. Однако (без любого тестирования вообще) я мог предположить, что его производительность довольно достойна, потому что рекурсия является на самом деле рекурсивным хвостом.

Мой вызов: дайте лучшую рекурсивную реализацию (на императивном языке). Вы говорите, что означает “better”: меньше кода, быстрее, я открыт для предложений.

private static StringBuilder RecJoin(IEnumerator<string> xs, string sep, StringBuilder result) {
    result.Append(xs.Current);
    if (xs.MoveNext()) {
        result.Append(sep);
        return RecJoin(xs, sep, result);
    } else
        return result;
}

public static string Join(this IEnumerable<string> xs, string separator) {
    var i = xs.GetEnumerator();
    if (!i.MoveNext())
        return string.Empty;
    else
        return RecJoin(i, separator, new StringBuilder()).ToString();
}
43
задан Bryan Ward 6 May 2013 в 21:49
поделиться

2 ответа

Я предполагаю, что вы действительно не хотите GROUP BY some_product.

Ответ на: «Есть ли способ GROUP BY для псевдонима столбца, такого как some_product, в этом случае, или мне нужно поместить это в подзапрос и сгруппировать который?" is: Вы не можете GROUP BY псевдоним столбца.

Предложение SELECT , в котором назначаются псевдонимы столбцов, обрабатывается только после предложения GROUP BY . Чтобы сделать результаты доступными для группировки, можно использовать встроенное представление или общее табличное выражение (CTE).

Встроенное представление:

select ...
from (select ... , CASE WHEN col1 > col2 THEN SUM(col3*col4) ELSE 0 END AS some_product
   from ...
   group by col1, col2 ... ) T
group by some_product ...

CTE:

with T as (select ... , CASE WHEN col1 > col2 THEN SUM(col3*col4) ELSE 0 END AS some_product
   from ...
   group by col1, col2 ... )
select ...
from T
group by some_product ... 
51
ответ дан 26 November 2019 в 22:48
поделиться

Если вы группируете по другому значению, то вместо того, что у вас есть,

запишите его как

Sum(CASE WHEN col1 > col2 THEN SUM(col3*col4) ELSE 0 END) as SumSomeProduct

Если, otoh, вы хотите сгруппировать по внутреннее выражение, (col3 * col4) затем

запишите группу By для соответствия выражению без SUM ...

Select Sum(Case When col1 > col2 Then col3*col4 Else 0 End) as SumSomeProduct
From ...

Group By Case When col1 > col2 Then col3*col4 Else 0 End 

Наконец, если вы хотите сгруппировать По фактическому агрегату

Select SumSomeProduct, Count(*), <other aggregate functions>
From (Select <other columns you are grouping By>, 
      Sum(Case When col1 > col2 
          Then col3*col4 Else 0 End) as SumSomeProduct
      From Table
      Group By <Other Columns> ) As Z
Group by SumSomeProduct
3
ответ дан 26 November 2019 в 22:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: