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

Откуда: From Russia
Сообщений: 146
Есть group by с приджойненной табличкой
SELECT AuthorID
FROM [Message]
JOIN Author on Message.AuthorID = Author.ID
GROUP BY [Message].[AuthorID]
Почему я не могу взять в select поле Author.Name? Ведь одной группе будет соответствовать только одно Author.Name, потому что AuthorID - primary key.
Делаю так:
SELECT AuthorID, MIN(Author.Name)
Есть более красивое решение?
10 июн 11, 10:57    [10794129]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Kudep,

ну так и добавьте поле Author.Name в список полей для группировки GROUP BY [Message].[AuthorID], Author.Name
10 июн 11, 11:05    [10794186]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Не слушайте SomewhereSomehow. Перенесите JOIN за пределы группировки.

Kudep
Ведь одной группе будет соответствовать только одно Author.Name
Сначало всё собирается во FROM в одну виртуальную таблицу, а потом группируется. И уже не важно из чего там оно собиралось до этого, данные (Author) вы уже бесполезно размножили для каждой строки.
10 июн 11, 11:08    [10794214]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Mnior,

что-то мне подсказывает, что оптимизатор не дурней велосипеда, для приведенного запроса, планы будут одинаковые, проверьте =)
10 июн 11, 11:13    [10794275]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
bibiskula
Member

Откуда: Пöндус(Инöстрäнный öгент)
Сообщений: 52988
Kudep
Есть group by с приджойненной табличкой
SELECT AuthorID
FROM [Message]
JOIN Author on Message.AuthorID = Author.ID
GROUP BY [Message].[AuthorID]
Почему я не могу взять в select поле Author.Name? Ведь одной группе будет соответствовать только одно Author.Name, потому что AuthorID - primary key.
Делаю так:
SELECT AuthorID, MIN(Author.Name)
Есть более красивое решение?


SELECT AuthorID, Author.Name
FROM [Message]
JOIN Author on Message.AuthorID = Author.ID
Вот! Красивее не бывает
10 июн 11, 11:18    [10794332]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
SomewhereSomehow
что-то мне подсказывает, что оптимизатор не дурней велосипеда
Надо не чувствовать, надо понимать.
SomewhereSomehow
проверьте =)
Тролите. Ладно, вот вам:

  |--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(int,[Expr1007],0)))
|--Stream Aggregate(GROUP BY:([M].[Author]) DEFINE:([Expr1007]=Count(*), [A].[Name]=ANY([tempdb].[dbo].[Author].[Name] as [A].[Name])))
|--Nested Loops(Inner Join, OUTER REFERENCES:([M].[Author]))
|--Sort(ORDER BY:([M].[Author] ASC))
| |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[Message].[PK_Message] AS [M]))
|--Clustered Index Seek(OBJECT:([tempdb].[dbo].[Author].[PK_Author] AS [A]), SEEK:([A].[ID]=[tempdb].[dbo].[Message].[Author] as [M].[Author]) ORDERED FORWARD)

|--Nested Loops(Inner Join, OUTER REFERENCES:([tempdb].[dbo].[Message].[Author]))
|--Compute Scalar(DEFINE:([Expr1003]=CONVERT_IMPLICIT(int,[Expr1008],0)))
| |--Stream Aggregate(GROUP BY:([tempdb].[dbo].[Message].[Author]) DEFINE:([Expr1008]=Count(*)))
| |--Sort(ORDER BY:([tempdb].[dbo].[Message].[Author] ASC))
| |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[Message].[PK_Message]))
|--Clustered Index Seek(OBJECT:([tempdb].[dbo].[Author].[PK_Author] AS [A]), SEEK:([A].[ID]=[tempdb].[dbo].[Message].[Author]) ORDERED FORWARD)
+ SQL
USE tempdb
GO
CREATE TABLE [dbo].[Author] (
	 [ID]	Int	IDENTITY
	 CONSTRAINT [PK_Author]	PRIMARY KEY
	,[Name]	Int	NOT NULL
)
CREATE TABLE [dbo].[Message] (
	 [ID]		Int	IDENTITY
	 CONSTRAINT [PK_Message]	PRIMARY KEY
	,[Author]	Int	NOT NULL
	 CONSTRAINT [FK_Message_Author]	REFERENCES [dbo].[Author]([ID])
)
GO
SET SHOWPLAN_TEXT ON
GO
SELECT	 M.Author
	,A.Name
	,Count(*)
FROM	     dbo.Message	M
	JOIN dbo.Author		A ON A.ID = M.Author
GROUP BY M.Author
	,A.Name
GO
SELECT	 M.Author
	,A.Name
	,M.[Count]
FROM (	SELECT	 Author
		,Count(*)	AS [Count]
	FROM	dbo.Message
	GROUP BY Author)	M
	JOIN dbo.Author		A ON A.ID = M.Author
GO
SET SHOWPLAN_TEXT OFF
GO
DROP TABLE [dbo].[Message]
DROP TABLE [dbo].[Author]
GO
Kudep, для удобства юзайте WITH:
;WITH GroupMessage AS (
	SELECT	 Author
		,Count(*)	AS [Count]
	FROM	dbo.Message
	GROUP BY Author
)SELECT	 M.Author
	,A.Name
	,M.[Count]
FROM	     GroupMessage	M
	JOIN dbo.Author		A ON A.ID = M.Author
10 июн 11, 20:34    [10799340]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Mnior,

т.е. вот так да? исключив полностью данные, вы решили не давать шансов оптимизатору? =)
внимание, коронный номер, перестаем дурить оптимизатор, и добавляем хоть какие-то строки (остальное, заметьте - не трогаем)
+

USE tempdb
GO
CREATE TABLE [dbo].[Author] (
	 [ID]	Int	IDENTITY
	 CONSTRAINT [PK_Author]	PRIMARY KEY
	,[Name]	Int	NOT NULL
)
CREATE TABLE [dbo].[Message] (
	 [ID]		Int	IDENTITY
	 CONSTRAINT [PK_Message]	PRIMARY KEY
	,[Author]	Int	NOT NULL
	 CONSTRAINT [FK_Message_Author]	REFERENCES [dbo].[Author]([ID])
)
GO
insert into [Author](Name) values (1),(2),(3),(4),(5)
insert into [Message]([Author]) values (1),(2),(3),(4),(5),(1),(2),(3),(4),(5)
go
SET SHOWPLAN_TEXT ON
GO
SELECT	 M.Author
	,A.Name
	,Count(*)
FROM	     dbo.Message	M
	JOIN dbo.Author		A ON A.ID = M.Author
GROUP BY M.Author
	,A.Name
GO
SELECT	 M.Author
	,A.Name
	,M.[Count]
FROM (	SELECT	 Author
		,Count(*)	AS [Count]
	FROM	dbo.Message
	GROUP BY Author)	M
	JOIN dbo.Author		A ON A.ID = M.Author
GO
SET SHOWPLAN_TEXT OFF
GO
DROP TABLE [dbo].[Message]
DROP TABLE [dbo].[Author]
GO

+

StmtText
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
|--Nested Loops(Inner Join, OUTER REFERENCES:([M].[Author]))
|--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(int,[Expr1007],0)))
| |--Stream Aggregate(GROUP BY:([M].[Author]) DEFINE:([Expr1007]=Count(*)))
| |--Sort(ORDER BY:([M].[Author] ASC))
| |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[Message].[PK_Message] AS [M]))
|--Clustered Index Seek(OBJECT:([tempdb].[dbo].[Author].[PK_Author] AS [A]), SEEK:([A].[ID]=[tempdb].[dbo].[Message].[Author] as [M].[Author]) ORDERED FORWARD)

(6 row(s) affected)

StmtText
-------------------------------------------------------------------------------------------------------------------------------------------------------
|--Nested Loops(Inner Join, OUTER REFERENCES:([tempdb].[dbo].[Message].[Author]))
|--Compute Scalar(DEFINE:([Expr1003]=CONVERT_IMPLICIT(int,[Expr1008],0)))
| |--Stream Aggregate(GROUP BY:([tempdb].[dbo].[Message].[Author]) DEFINE:([Expr1008]=Count(*)))
| |--Sort(ORDER BY:([tempdb].[dbo].[Message].[Author] ASC))
| |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[Message].[PK_Message]))
|--Clustered Index Seek(OBJECT:([tempdb].[dbo].[Author].[PK_Author] AS [A]), SEEK:([A].[ID]=[tempdb].[dbo].[Message].[Author]) ORDERED FORWARD)

(6 row(s) affected)

Mnior,
когда-то давно я переписывал запросы, в доставшейся мне базе, так, как вы сейчас посовтовали, т.к. это мне казалось логичнее. Пока не понял, что этих запросов много, а меня обуяла лень - тогда я решил проверить, насколько овчинка стоит выделки и сравнить производительность, после чего увидел, что везде в простых случаях оптимизатор и сам справляется, после чего вздохнул с облегчением и забил на это дело.
В данном случае, я вообще пока склонен присоединиться к мнению bibiskula, т.к. никаких резонов для группировки ТС не представил. А меряться производительностью на чисто академических задачах - может привести к конфузу =)
10 июн 11, 23:19    [10800049]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
No GROUP BY:

SELECT Author.ID, Author.Name
FROM Author
WHERE EXISTS 
  (SELECT * FROM Message where Message.AuthorID = Author.ID)
11 июн 11, 03:19    [10801086]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
SomewhereSomehow
т.е. вот так да? исключив полностью данные, вы решили не давать шансов оптимизатору? =)
Баг на баге. Доколе железная логика будет стоять ниже статистики, а это один из 100500 случаев. Будем регить.
SomewhereSomehow
перестаем дурить оптимизатор
Ну он сам виноват, что тупой.

SomewhereSomehow, вы правы. Удивительно что в реальности в основном совпадает как у меня в примере. Ибо переписывал кучу запросов, т.к. план был мерзопакостный.

SomewhereSomehow
когда-то давно я переписывал запросы
Это большая ошибка, планы надо смотреть всегда. Вы забыли основную проблему? - время оптимизации ограниченно Поэтому на сложных запросах (не этих детских шалостей) такое не канает. Это первое.
SomewhereSomehow
что везде в простых случаях
Во во. Это вы понимаете. Не лениво вносить "разнообразие"?

Второе, дописывать руками в GROUP BY ради лени - вброс не засчитан (ну разве что на мелких запросах) ибо WITH короче, и самое главное понятнее. Мухи, котлеты и всё такое.

Скажу одно, выражение "тяжело лопатить много текста" не верно. Нет оно верно для вас например, но не верно для меня. Какгрится "Что не убивает - делает нас сильней". Лопатив гигабайты кода скилл увеличивается на пару порядков, поэтому выровнять кривые руки во всём коде не тяжелее, чем написать маленький костыль.
Не лень двигатель, а прямые мозги. Уберёте лень - получите гениальность. Так что не ленитесь. ;)


SomewhereSomehow, спасибо. Ещё одна тема! Жаль что пора отпусков, iljy и других нет на месте (форум мёртвый).
Оптимизатор часто тупит, и рассчитывать на повышение на более высокий уровень логического вывода даже не приходится.
Повторюсь: Почему железная логика стоит ниже статистики?

Давайте опять "обдурим" оптимизатор и поставим везде LEFT:
	LEFT JOIN dbo.Author	A ON A.ID = M.Author
Всё, план опять съехал.
И не лень учитывать столько факторов? Может проще писать одинаково, просто и надёжно.

И меня это напрягло, а вот почему:
Частенько во VIEW пишу LEFT из-за одной очень удобной особенности (но в целом тупости) оптимизатора - только так он исключает таблицу из запроса, если не были выбраны по ней колонки.
По идее он должен был убрать и при простом JOIN, зачем же бесполезно проверять повторно существование строки при CHECK-нутом FOREIGN KEY?
11 июн 11, 14:26    [10801575]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
ViPRos
Member

Откуда:
Сообщений: 9946
Mnior,

убыстрите эту процедуру , пиво поставлю с шашлычком

ALTER PROCEDURE [dbo].[GetFreeTimeBlockForPowerDirect] 
 @proc uniqueidentifier,	
 @dn datetime,
 @dk datetime,
 @power numeric(5,2)
AS
BEGIN
	 SET NOCOUNT ON;
	
	 with t0 ([Дата начала],
	 		  [Дата окончания],
	 		  [Потребляемая мощность, процент])
	 as
	 (
	 	select [dbo].[Процессор процесса расчетного].[Дата начала],
	 		   [dbo].[Процессор процесса расчетного].[Дата окончания],
	 		   [dbo].[Процессор процесса расчетного].[Потребляемая мощность, процент]
	 	from [dbo].[Процессор процесса расчетного]
	 	where [dbo].[Процессор процесса расчетного].[Процессоры] = @proc and [dbo].[Процессор процесса расчетного].[Потребляемая мощность, процент] > 0
	 )
     select min(t4.Дата) Дата from
	 (select t3.Дата,
	  max(case when t2.Мощность + @power > 100 OR t2.Дата < @dn then 1 else 0 end) НеУдовлетворяетОграничениюПоМощьности
	  from 
	  (select t1.Дата, sum(ISNULL(case when t1.Дата <> t0.[Дата окончания] then t0.[Потребляемая мощность, процент] else 0 end,0)) Мощность 
       from 
      (select [Дата начала] Дата from t0
 	   union 
	   select [Дата окончания] Дата from t0
	   union 
	   select @dn)
	  t1 left outer join t0
	  on t1.Дата >= t0.[Дата начала] and t1.Дата <= t0.[Дата окончания]
      group by t1.Дата)
	  t2,
      (select [Дата начала] Дата from t0
 	   union 
	   select [Дата окончания] Дата from t0
	   union 
	   select @dn)
	  t3
	  where t3.Дата <= t2.Дата and t2.Дата <= DATEADD("ss", DATEDIFF("ss" ,@dn, @dk), t3.Дата)
      group by t3.Дата)
    t4
    where
    t4.НеУдовлетворяетОграничениюПоМощьности = 0

END
11 июн 11, 14:58    [10801636]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Mnior
Это большая ошибка, планы надо смотреть всегда.
Ну дык, это когда было, я тогда еще и страшных слов-то таких не знал, вот и маялся фигней =)
Затишье наверное потому как на дачах все. У нас даже проблем с парковкой возле дома нет, что странно, обычно к вечеру даж в выходные все забито.
11 июн 11, 17:40    [10801974]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
ViPRos
пиво поставлю с шашлычком
Работаю за еду
Предоплата: Chateau Lafite 1787 года
12 июн 11, 18:38    [10804083]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
ViPRos
Member

Откуда:
Сообщений: 9946
Mnior,

ну, значит и без пиво останешься :)
ишь че захотел, я мес продаю за 100000$, а этому бутылку за 150000$ давай
MSSQL можно переписать за такие бабки
12 июн 11, 20:17    [10804303]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
ViPRos
ну, значит и без пиво останешься
Му-ха-ха.
ViPRos
продаю за 100000$
Дорогое же у вас пивко с закуской.

ViPRos, бизнес должен понять, что специалисты на дороге не валяются, их нужно выращивать. Как в матрице.
В принципе это должная быть единственная их цель, а не грести лопатой за бесплатно.

ViPRos
MSSQL можно переписать за такие бабки
А мысля хорошая.
Декларативный скуль есть только у MS, все остальные ломанулись по тупиковой оракакловской ветке.
Давно уже как пора, а то MS уже буксует на месте. Если бы не патенты на воздух, конечно.

ViPRos, только есть одно НО, уже некому. Про...ли полимеры.

А 150K это даже на воду электричество не хватит. Но дело даже не в этом.
12 июн 11, 21:36    [10804488]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Mnior
ViPRos, бизнес должен понять, что специалисты на дороге не валяются, их нужно выращивать.

+100
Mnior
А 150K это даже на воду электричество не хватит.
+100 500
12 июн 11, 23:01    [10804734]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
ViPRos, уже можно поставить бан за несоблюдение правил форума (невтемность и эээ неуважение).
Но можно отыграться на вашем крайнем говно-коде. Немного выправил, чтоб хоть чуть понятнее было:
CREATE FUNCTION [dbo].[fnFreeTimeBlockForPowerDirect] (
	 @Processor	UniqueIdentifier
	,@From		DateTime
	,@To		DateTime
	,@Power		Numeric(5,2)
) RETURNS TABLE AS RETUN
WITH [Мощность] AS (
	SELECT	 P.[Дата начала]
		,P.[Дата окончания]				-- И шо, они ещё и пересекаются?
		,P.[Потребляемая мощность, процент]
	FROM	dbo.[Процессор процесса расчетного]	P
	WHERE	    P.[Процессоры]			= @Processor
		AND P.[Потребляемая мощность, процент]	> 0	-- Нафига записи = 0?	А почему не учитываются? - Мухлюете, опсосы.
), [Точки отсчёта] ([Дата]) AS (
	SELECT	[Дата начала]		FROM [Мощность]
UNION	SELECT	[Дата окончания]	FROM [Мощность]
) , [Нагрузка] ([Дата], [Мощность]) AS (			-- Точно, пересекаются! 8-o
	SELECT	 T.Дата
		,Sum(IsNull(P.[Потребляемая мощность, процент],0))
	FROM	          [Точки отсчёта]	T
		LEFT JOIN [Мощность]		P ON P.[Дата начала]	<= T.Дата
						 AND P.[Дата окончания]	>  T.Дата
	GROUP BY T.Дата
)	SELECT	Top(1) T.Дата
	FROM	[Точки отсчёта]	T
	WHERE	    T.Дата	< DateAdd(Second,-DateDiff(Second,@From,@To),@From)
		AND NOT Exists(
			SELECT	*
			FROM	[Нагрузка] G
			WHERE	    G.Дата	>= T.Дата
				AND G.Дата	<= DateAdd(Second,DateDiff(Second,@From,@To),T.Дата)	-- WTF? У временного отрезка всегда одна точка выколота!
				AND G.Мощность	<= 100 - @Power)					-- Не удовлетворяет ограничению по мощности
	ORDER BY T.Дата
GO
Это надо было так запутать. Хотя там спроектировано вообще левой пяткой.
Не говоря, что это всё неправильно, т.к. можно распределять куски в другом порядке и больше впихнуть.
NP полная.

Вместо того, что-бы просто хранить в табле одну дату и тупо считать потребление, они тут накручивают.
DECLARE	@TPower TABLE (
	 [Process]	Int
	,[Date]		DateTime			-- Первая запись = начало отсчёта, вывернуто
--	,Delda		Int	-- В секундах, или предыдущее время
	,[Power]	SmallMoney	NOT NULL	-- Первая запись = 0
	 CHECK ([Power] >= 0 AND [Power] <= 100)
--	,[PowerSum]	Money	-- Сразу и подсчитывать
	,PRIMARY KEY (
		 [Process]
		,[Date]
	)
	,UNIQUE	([Process]
		,[Power]	-- Так можно было бы быстро искать дырки
		,[Date]
	)
)
-- Но лучше честно:
SELECT	 T.Process
	,Sum(DateDiff(Second,P.[Date],T.[Date]) * T.[Power])
FROM	@TPower T OUTER APPLY (
		SELECT	Top(1) P.[Date]
		FROM	@TPower P
		WHERE	    T.Process = @Process
			AND T.Process = @Process
		ORDER BY P.[Date] DESC) P
GROUP BY T.Process
13 июн 11, 01:29    [10805069]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
ViPRos
Member

Откуда:
Сообщений: 9946
Mnior
ViPRos, уже можно поставить бан за несоблюдение правил форума (невтемность и эээ неуважение).
Но можно отыграться на вашем крайнем говно-коде. Немного выправил, чтоб хоть чуть понятнее было:
CREATE FUNCTION [dbo].[fnFreeTimeBlockForPowerDirect] (
	 @Processor	UniqueIdentifier
	,@From		DateTime
	,@To		DateTime
	,@Power		Numeric(5,2)
) RETURNS TABLE AS RETUN
WITH [Мощность] AS (
	SELECT	 P.[Дата начала]
		,P.[Дата окончания]				-- И шо, они ещё и пересекаются?
		,P.[Потребляемая мощность, процент]
	FROM	dbo.[Процессор процесса расчетного]	P
	WHERE	    P.[Процессоры]			= @Processor
		AND P.[Потребляемая мощность, процент]	> 0	-- Нафига записи = 0?	А почему не учитываются? - Мухлюете, опсосы.
), [Точки отсчёта] ([Дата]) AS (
	SELECT	[Дата начала]		FROM [Мощность]
UNION	SELECT	[Дата окончания]	FROM [Мощность]
) , [Нагрузка] ([Дата], [Мощность]) AS (			-- Точно, пересекаются! 8-o
	SELECT	 T.Дата
		,Sum(IsNull(P.[Потребляемая мощность, процент],0))
	FROM	          [Точки отсчёта]	T
		LEFT JOIN [Мощность]		P ON P.[Дата начала]	<= T.Дата
						 AND P.[Дата окончания]	>  T.Дата
	GROUP BY T.Дата
)	SELECT	Top(1) T.Дата
	FROM	[Точки отсчёта]	T
	WHERE	    T.Дата	< DateAdd(Second,-DateDiff(Second,@From,@To),@From)
		AND NOT Exists(
			SELECT	*
			FROM	[Нагрузка] G
			WHERE	    G.Дата	>= T.Дата
				AND G.Дата	<= DateAdd(Second,DateDiff(Second,@From,@To),T.Дата)	-- WTF? У временного отрезка всегда одна точка выколота!
				AND G.Мощность	<= 100 - @Power)					-- Не удовлетворяет ограничению по мощности
	ORDER BY T.Дата
GO
Это надо было так запутать. Хотя там спроектировано вообще левой пяткой.
Не говоря, что это всё неправильно, т.к. можно распределять куски в другом порядке и больше впихнуть.
NP полная.

Вместо того, что-бы просто хранить в табле одну дату и тупо считать потребление, они тут накручивают.
DECLARE	@TPower TABLE (
	 [Process]	Int
	,[Date]		DateTime			-- Первая запись = начало отсчёта, вывернуто
--	,Delda		Int	-- В секундах, или предыдущее время
	,[Power]	SmallMoney	NOT NULL	-- Первая запись = 0
	 CHECK ([Power] >= 0 AND [Power] <= 100)
--	,[PowerSum]	Money	-- Сразу и подсчитывать
	,PRIMARY KEY (
		 [Process]
		,[Date]
	)
	,UNIQUE	([Process]
		,[Power]	-- Так можно было бы быстро искать дырки
		,[Date]
	)
)
-- Но лучше честно:
SELECT	 T.Process
	,Sum(DateDiff(Second,P.[Date],T.[Date]) * T.[Power])
FROM	@TPower T OUTER APPLY (
		SELECT	Top(1) P.[Date]
		FROM	@TPower P
		WHERE	    T.Process = @Process
			AND T.Process = @Process
		ORDER BY P.[Date] DESC) P
GROUP BY T.Process


Да они перескаются.
Запись с 0 мощностью нужна для документирования работы и показа на ганте.
Все там правильно. Архитектуры могут быть разные. Это как раз неудачная (просто почему то тут я решил экономить память и заниматься динамическими расчетами). Лучшье когда отдельно храним и недоступность и доступность и нифига не вычисляем (так и сделана в последней версии, выигрыш в 4 порядка).

Косметика тебе нужна была, что бы понять что там написано (вроде по комментам все понял правильно), а погоду не делает.
Но, запрос последний показал, что не все ты понял или решил шифроваться наподобие фаулеров долбаных, которые или невтерпеже или умышленно пишут неправильный код.
Чо за потребление ты там считаешь?

Моя задача - найти доступный отрезок с заданной мощностью начиная с заданной даты для заданного процессора.
13 июн 11, 03:43    [10805188]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
ViPRos
Да они перескаются.
И? Где абяснения.
Если избавится от него, то не надо ни UNION ни тройной подзапрос.
P.[Потребляемая мощность, процент] > 0 только мешает, т.к. только из-за него и LEFT JOIN пришлось писать.

ViPRos
Косметика тебе нужна была, что бы понять что там написано (вроде по комментам все понял правильно)
Да, да. А до некоторых даже и так не доходит.
ViPRos
а погоду не делает
Естественно. Архитектура говно. А из него цвэточек не выйдет. Запросом показал:
1. как его можно извратить (см ваш первоначальный вариант)
2. фиговость архитектуры

ViPRos
фаулеров долбаных
Кто бы писал. Не соблюдение правил форума, неуважение к окружающим (как по обращению так и тем что код неформатированный).
Нетерпением и непониманием того что запросы мной представленные писались в gedit-е.
ViPRos
Моя задача - найти доступный отрезок с заданной мощностью начиная с заданной даты для заданного процессора.
Вот сама эта задачи и вызывает кучу недоумения. Зачем?
Во вторых, в запросе стоит Top(1), в задаче этого не сказано, а если будет несколько запросов подряд, то распределить "доступные отрезки" можно огромным количеством способов (см. задачу о рюкзаке, а она NP полная).

SELECT	 T.Process
	,Sum(DateDiff(Second,P.[Date],T.[Date]) * T.[Power])
FROM	@TPower T OUTER APPLY (
		SELECT	Top(1) P.[Date]
		FROM	@TPower P
		WHERE	P.Process = T.Process
		ORDER BY P.[Date] DESC) P
GROUP BY T.Process
Т.е. тупо подсчитывать потребление в попугаях. Вы потребили 42 процесс часов из 108, вам осталось 66.
14 июн 11, 14:52    [10810691]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
ViPRos
Member

Откуда:
Сообщений: 9946
Mnior,

1. Я распределяю не нормочасы(не объем), а точно выделяю ВРЕМЯ и ПРОДОЛЖИТЕЛЬНОСТЬ ПОТРЕБЛЕНИЯ МОЩНОСТИ.
Пример.
Процессор1 занять с Дата1 до Дата2. Эта работа Потребляет 25% Мощности Процессора.
Процессор1 занять с Дата3 (Дата3 < Дата1) до Дата4 (Дата4 > Дата1). Эта работа Потребляет 20% Мощности Процессора.
Процессор1 занять с Дата5 (Дата5 < Дата2) до Дата6 (Дата6 > Дата2). Эта работа Потребляет 20% Мощности Процессора.
...

То есть , пока суммарно не достигнут предел (допустим 85% разрешено к потреблению каждый момент) можно работы "наложить" друг на друга во времени. Получается ступенчантый график потребления мощности во времени.

2. Ну, проверку на 0 можно и выкинуть.

3. Top 1 - один из возможных вариантов запроса. Можно вернуть все отрезки для одного проца или для многих процов минимальный или все для всех и т.д.

4. То, что подход "в лоб" (зато "красив") я уже говорил. Есть другие "некрасивые" (что то исключает многопоточность, что то заставляет пользоваться нежелательными артефактами и т.д.) подходы, которые ооочень быстры. Но меня сильно зацепил этот запрос, он какой то Особо нелинейный, непонятно когда и за счет чего получается экспо взрыв. Потому я и все время возвращаюсь к нему.

4. Где ты видишь неуважение? Если не оценил бы как спеца то и не обратился лично.

5. Твой запрос для объемов. Конечно его можно быстро приспособить и с учетом продолжительности, но если хорошо посмотреть, то получится то что выложил я.

Запрос для одного процессора должен вернуть:
[Дата начала](>= требуемой), [Дата окончания], [Свободная мощность] (>= требуемой)
14 июн 11, 16:27    [10811446]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по group by  [new]
ViPRos
Member

Откуда:
Сообщений: 9946
Mnior
ViPRos
Моя задача - найти доступный отрезок с заданной мощностью начиная с заданной даты для заданного процессора.
Вот сама эта задачи и вызывает кучу недоумения. Зачем?


Я свожу задачу к матроидообразной фигне и пытаюсь жадно выбрать лучший процессор, что бы уйти от NP (в любом случае дядя Ваня сделает хуже при заданных ограничениях).
14 июн 11, 16:36    [10811526]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить