Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Зачем тут MAX, MIN?  [new]
Relic Hunter
Member

Откуда: AB
Сообщений: 7599
В чужем коде замечаю применение агрегатных фунций к текстовым полям. Не пойму какaя логика тут?
+
SELECT
	Employee = @Employee,
	StartDate = CONVERT(/*N*/varchar(10),@StartDate,121),
	EndDate = CONVERT(/*N*/varchar(10),@EndDate,121),
	tkUnitDetail.Seq,
	tkUnitDetail.WBS1, MAX(PR1.Name) As WBS1Name, MAX(CL.Name) As ClientName, MAX(PR1.SubLevel) As WBS2Level,
	MAX(PR1.ChargeType) As ChargeType,
	tkUnitDetail.WBS2, MAX(CASE WHEN tkUnitDetail.WBS2 = /*N*/'' THEN /*N*/'' ELSE PR2.Name END) As WBS2Name, MAX(PR2.SubLevel) As WBS3Level,
	tkUnitDetail.WBS3, MAX(CASE WHEN tkUnitDetail.WBS3 = /*N*/'' THEN /*N*/'' ELSE PR3.Name END) As WBS3Name,

	MIN(tkUnitDetail.Unit) AS Unit, MIN(tkUnitDetail.UnitTable) AS UnitTable,
	MIN(UN.Name) AS UnitDescription 
	MIN(UN.PluralLabel) AS UOM,

	MIN(CFGMainData.FunctionalCurrencyCode) AS FunctionalCurrencyCode, 
	MIN(PR1.ProjectCurrencyCode) AS CurrencyCode, 
	MIN(PR1.BillingCurrencyCode) AS BillingCurrencyCode, 
	MIN(PR3.Org) AS Org, 
	MIN(PR3.UnitTable) AS DefaultUnitTable 
FROM
	CFGMainData,
	tkUnitDetail
	LEFT JOIN PR AS PR1 ON PR1.WBS1 = tkUnitDetail.WBS1 --AND PR1.WBS2 = ' ' AND tkUnitDetail.WBS3 = ' '
	LEFT JOIN PR AS PR2 on PR2.WBS1 = tkUnitDetail.WBS1 AND PR2.WBS2 = tkUnitDetail.WBS2 --AND PR2.WBS3 = ' ' AND PR2.WBS2 <> ' '
	LEFT JOIN PR AS PR3 on PR3.WBS1 = tkUnitDetail.WBS1 AND PR3.WBS2 = tkUnitDetail.WBS2 AND PR3.WBS3 = tkUnitDetail.WBS3 --AND PR3.WBS3 <> ' '
	LEFT JOIN CL ON PR1.ClientID = CL.ClientID
	LEFT JOIN UN ON tkUnitDetail.UnitTable = UN.UnitTable AND tkUnitDetail.Unit = UN.Unit AND UN.Company = @activeCompany
WHERE
	CFGMainData.Company = @activeCompany AND 
	Employee = @Employee AND
	tkUnitDetail.EndDate = @EndDate AND
	PR1.WBS2 = /*N*/' ' AND
	PR1.WBS3 = /*N*/' ' AND
	PR2.WBS3 = /*N*/' '
GROUP BY
	tkUnitDetail.WBS1, tkUnitDetail.WBS2, tkUnitDetail.WBS3, tkUnitDetail.Seq
ORDER BY
	Seq
20 ноя 15, 02:48    [18444749]     Ответить | Цитировать Сообщить модератору
 Re: Зачем тут MAX, MIN?  [new]
Добрый Э - Эх
Guest
Relic Hunter,

у тебя запрос с группировкой. стало быть, для успешной его работы ВСЕ поля из списка SELECT должны быть либо во фразе GROUP BY, либо под агрегатными функциями.
20 ноя 15, 04:32    [18444815]     Ответить | Цитировать Сообщить модератору
 Re: Зачем тут MAX, MIN?  [new]
Relic Hunter
Member

Откуда: AB
Сообщений: 7599
Добрый Э - Эх,

А это? По ним группироки нету.
MAX(PR1.Name) As WBS1Name, MAX(CL.Name) As ClientName, MAX(PR1.SubLevel) As WBS2Level,
MIN(tkUnitDetail.Unit) AS Unit, MIN(tkUnitDetail.UnitTable) AS UnitTable,
	MIN(UN.Name) AS UnitDescription 
	MIN(UN.PluralLabel) AS UOM,

	MIN(CFGMainData.FunctionalCurrencyCode) AS FunctionalCurrencyCode, 
	MIN(PR1.ProjectCurrencyCode) AS CurrencyCode, 
	MIN(PR1.BillingCurrencyCode) AS BillingCurrencyCode, 
	MIN(PR3.Org) AS Org, 
	MIN(PR3.UnitTable) AS DefaultUnitTable 
20 ноя 15, 04:43    [18444821]     Ответить | Цитировать Сообщить модератору
 Re: Зачем тут MAX, MIN?  [new]
Relic Hunter
Member

Откуда: AB
Сообщений: 7599
Добрый Э - Эх,

Да, и для MIN, MAX группировка не нужна.

SELECT MAX('Да, и для MIN, MAX группировка не нужна.')
SELECT MIN('Да, и для MIN, MAX группировка не нужна.')
20 ноя 15, 04:50    [18444822]     Ответить | Цитировать Сообщить модератору
 Re: Зачем тут MAX, MIN?  [new]
Добрый Э - Эх
Guest
Relic Hunter,

ещё раз. у тебя запрос с группировкой (в нем есть фраза GROUP BY). И в этом случае ВСЕ поля из списка SELECT должны быть ИЛИ в предложении GROUP BY, или под АГРЕГАТНОЙ ФУНКЦИЕЙ.
20 ноя 15, 05:23    [18444835]     Ответить | Цитировать Сообщить модератору
 Re: Зачем тут MAX, MIN?  [new]
Добрый Э - Эх
Guest
Relic Hunter
Добрый Э - Эх,

А это? По ним группироки нету.
MAX(PR1.Name) As WBS1Name, MAX(CL.Name) As ClientName, MAX(PR1.SubLevel) As WBS2Level,
MIN(tkUnitDetail.Unit) AS Unit, MIN(tkUnitDetail.UnitTable) AS UnitTable,
	MIN(UN.Name) AS UnitDescription 
	MIN(UN.PluralLabel) AS UOM,

	MIN(CFGMainData.FunctionalCurrencyCode) AS FunctionalCurrencyCode, 
	MIN(PR1.ProjectCurrencyCode) AS CurrencyCode, 
	MIN(PR1.BillingCurrencyCode) AS BillingCurrencyCode, 
	MIN(PR3.Org) AS Org, 
	MIN(PR3.UnitTable) AS DefaultUnitTable 
gj по ним группировки нет. факт. но именно поэтому они и засунуты под агрегатные функции.
20 ноя 15, 05:25    [18444836]     Ответить | Цитировать Сообщить модератору
 Re: Зачем тут MAX, MIN?  [new]
aleks2
Guest
Добрый Э - Эх
Relic Hunter
Добрый Э - Эх,

А это? По ним группироки нету.
MAX(PR1.Name) As WBS1Name, MAX(CL.Name) As ClientName, MAX(PR1.SubLevel) As WBS2Level,
MIN(tkUnitDetail.Unit) AS Unit, MIN(tkUnitDetail.UnitTable) AS UnitTable,
	MIN(UN.Name) AS UnitDescription 
	MIN(UN.PluralLabel) AS UOM,

	MIN(CFGMainData.FunctionalCurrencyCode) AS FunctionalCurrencyCode, 
	MIN(PR1.ProjectCurrencyCode) AS CurrencyCode, 
	MIN(PR1.BillingCurrencyCode) AS BillingCurrencyCode, 
	MIN(PR3.Org) AS Org, 
	MIN(PR3.UnitTable) AS DefaultUnitTable 
gj по ним группировки нет. факт. но именно поэтому они и засунуты под агрегатные функции.


Ниправильно объясняешь.
99.9% это говнокод, когда под группировку сунуты лишние таблицы.
20 ноя 15, 08:10    [18444965]     Ответить | Цитировать Сообщить модератору
 Re: Зачем тут MAX, MIN?  [new]
Glory
Member

Откуда:
Сообщений: 104751
Relic Hunter
Да, и для MIN, MAX группировка не нужна.

Ну так уберите их тогда из вашего запроса и тогда вы точно узнаете
20 ноя 15, 09:20    [18445168]     Ответить | Цитировать Сообщить модератору
 Re: Зачем тут MAX, MIN?  [new]
baza906
Member

Откуда:
Сообщений: 283
Relic Hunter, создателю кода требовалось получить по одной строке на каждое сочетание tkUnitDetail.WBS1, tkUnitDetail.WBS2, tkUnitDetail.WBS3, tkUnitDetail.Seq. Так как каким то рациональным способом этого добиться не удалось, было принято решение проагрегировать по этим столбцам, а по остальным просто брать одно из значений по принципу mim/max. Потому что вряд ли, к примеру, в требованиях к запросу требовался вывод Name, по принципу алфавитного порядка MIN(UN.Name).

Если это так, в запросе логичнее использовать first_value()
20 ноя 15, 13:13    [18447057]     Ответить | Цитировать Сообщить модератору
 Re: Зачем тут MAX, MIN?  [new]
msLex
Member

Откуда:
Сообщений: 9290
baza906
...
в запросе логичнее использовать first_value()


а ничего, что first_value() как бы не агрегатная, а оконная функция?
20 ноя 15, 13:16    [18447090]     Ответить | Цитировать Сообщить модератору
 Re: Зачем тут MAX, MIN?  [new]
baza906
Member

Откуда:
Сообщений: 283
msLex, с дальнейшей агрегацией, не стал писать
20 ноя 15, 13:37    [18447264]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить