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

Откуда:
Сообщений: 23
Есть таблица в которой (помимо полей с ID сотрудника и тд.) каждый день представлен новым полем eosD01...eosD31 - varchar(11)
Вносятся данные вида: В - выходной, О - отпуск, Б - больничный или, например, 09:00-18:00 - рабочая смена.

Задача минимум: вывести количество выходных дней
Задача максимум: ОДНИМ ЗАПРОСОМ вывести (естественно, в три поля) количество выходных, больничных, отпусков

Реализация для задачи минимум:

SELECT eosEmployeeID as EmployeeID,

(CASE WHEN eosD01 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD02 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD03 = 'В' THEN 1 ELSE 0 END)+
(CASE WHEN eosD04 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD05 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD06 = 'В' THEN 1 ELSE 0 END)+
(CASE WHEN eosD07 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD08 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD09 = 'В' THEN 1 ELSE 0 END)+
(CASE WHEN eosD10 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD11 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD12 = 'В' THEN 1 ELSE 0 END)+
(CASE WHEN eosD13 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD14 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD15 = 'В' THEN 1 ELSE 0 END)+
(CASE WHEN eosD16 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD17 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD18 = 'В' THEN 1 ELSE 0 END)+
(CASE WHEN eosD19 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD20 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD21 = 'В' THEN 1 ELSE 0 END)+
(CASE WHEN eosD22 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD23 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD24 = 'В' THEN 1 ELSE 0 END)+
(CASE WHEN eosD25 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD26 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD27 = 'В' THEN 1 ELSE 0 END)+
(CASE WHEN eosD28 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD29 = 'В' THEN 1 ELSE 0 END)+(CASE WHEN eosD30 = 'В' THEN 1 ELSE 0 END)+
(CASE WHEN eosD31 = 'В' THEN 1 ELSE 0 END) AS WeekendQTY

FROM EmployeeOperatingSchedule
WHERE eosMonthID=8 and eosYearID = 2014
Order by eosEmployeeID

Есть ли более, скажем так, компактное/утонченное решение? Ведь для отпусков и больничных мне придется повторить код дважды.
30 авг 14, 11:27    [16515833]     Ответить | Цитировать Сообщить модератору
 Re: Пожалуйста, помогите отпимизировать запрос по вычислению кол-ва выходных дней в графике  [new]
invm
Member

Откуда: Москва
Сообщений: 9646
unpivot + sum + group by
30 авг 14, 11:50    [16515879]     Ответить | Цитировать Сообщить модератору
 Re: Пожалуйста, помогите отпимизировать запрос по вычислению кол-ва выходных дней в графике  [new]
alex_forw
Member

Откуда:
Сообщений: 23
invm
unpivot + sum + group by


unpivot - ??
sum - пробовал, суммируются значения в поле попадающие под условие, а не количество самих полей
30 авг 14, 11:55    [16515890]     Ответить | Цитировать Сообщить модератору
 Re: Пожалуйста, помогите отпимизировать запрос по вычислению кол-ва выходных дней в графике  [new]
alex_forw
Member

Откуда:
Сообщений: 23
Да, забыл уточнить. SQL Server 2000
30 авг 14, 11:55    [16515892]     Ответить | Цитировать Сообщить модератору
 Re: Пожалуйста, помогите отпимизировать запрос по вычислению кол-ва выходных дней в графике  [new]
aleks2
Guest
SELECT eosEmployeeID as EmployeeID,
   (select count(*)
       from ( select eosD01 as x
                union all select eosD02
                union all select eosD03
                ...
                union all select eosD031
        ) as y
     where x = 'B'
   ) AS WeekendQTY
FROM EmployeeOperatingSchedule
WHERE eosMonthID=8 and eosYearID = 2014
Order by eosEmployeeID


Не сильно компактнее, но повторное использование проще - только тут сменить:
     where x = 'B'
30 авг 14, 12:34    [16515953]     Ответить | Цитировать Сообщить модератору
 Re: Пожалуйста, помогите отпимизировать запрос по вычислению кол-ва выходных дней в графике  [new]
alex_forw
Member

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

Вариант интересен, хоть и более ресурсоемок, как мне кажется судя по плану
Но проблемы тройного повторения куска кода, увы, не решает.


(select count(*)
from ( select eosD01 as x
union all select eosD02
union all select eosD03
...
union all select eosD031
) as y
where x = 'B'
) AS WeekendQTY


Я так понимаю, этого вообще не избежать?
30 авг 14, 14:36    [16516117]     Ответить | Цитировать Сообщить модератору
 Re: Пожалуйста, помогите отпимизировать запрос по вычислению кол-ва выходных дней в графике  [new]
alex_forw
Member

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

И да - СПАСИБО :)
30 авг 14, 14:37    [16516118]     Ответить | Цитировать Сообщить модератору
 Re: Пожалуйста, помогите отпимизировать запрос по вычислению кол-ва выходных дней в графике  [new]
invm
Member

Откуда: Москва
Сообщений: 9646
alex_forw
Я так понимаю, этого вообще не избежать?
Можно.
1. Создаем представление:
create view dbo.vEmployeeOperatingScheduleUnpivoted
as
select
 t.eosEmployeeID as EmployeeID
 t.eosMonthID as MonthID,
 t.eosYearID as YearID,
 case n.n
  when 1 then t.eosD01
  when 2 then t.eosD02
  ...
  when 31 then t.eosD31
 end as D
from
 EmployeeOperatingSchedule t cross join
 (select 1 union all select 2 ... union all select 31) n(n)
go

2. Сам запрос:
select
 EmployeeID,
 count(case when D = 'В' then 1 end) as [Выходных],
 count(case when D = 'О' then 1 end) as [Отпускных]
from
 dbo.vEmployeeOperatingScheduleUnpivoted
where
 MonthID = 8 and YearID = 2014
group by
 EmployeeID
order by
 EmployeeID;
30 авг 14, 14:56    [16516137]     Ответить | Цитировать Сообщить модератору
 Re: Пожалуйста, помогите отпимизировать запрос по вычислению кол-ва выходных дней в графике  [new]
aleks2
Guest
alex_forw
Я так понимаю, этого вообще не избежать?

1. Ну, в старших версиях - cross apply ё.

2. Насчет "ресурсоемче" - перекрестись. С какого бодуна это сложнее твоей груды кейзов?
30 авг 14, 15:49    [16516173]     Ответить | Цитировать Сообщить модератору
 Re: Пожалуйста, помогите отпимизировать запрос по вычислению кол-ва выходных дней в графике  [new]
aleks2
Guest
invm
1. Создаем представление:

Что я вижу?!
Борец за эффективность снова предлагает неэффективные решения?
30 авг 14, 16:02    [16516175]     Ответить | Цитировать Сообщить модератору
 Re: Пожалуйста, помогите отпимизировать запрос по вычислению кол-ва выходных дней в графике  [new]
alex_forw
Member

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

Благодарю:) Код сокращается все больше и больше:)
Правда, пошел несколько иным путем, не создавал представление ибо держать в нем миллион миллионов записей, в зависимости от роста таблицы, не хочу. А просто, на основе вашего кода, создал запрос с использованием временной таблицы и указанием параметров (месяц, год) выборки, дабы сократить кол-во инфы.

Вот, что получилось. Есть замечания, предложения?

Declare @t Table (EmployeeID int, DaysList varchar(11))
Insert Into @t
select
 eosEmployeeID, 

(CASE n.n
	 When 1  then eosD01 When 2  then eosD02 When 3  then eosD03 
         ...
	 When 31 then eosD31 
END) as DaysList

From EmployeeOperatingSchedule cross join

(Select 1 union all Select 2 union all Select 3 union all 
 ...
 Select 31) 
n(n)

Where
 eosMonthID = 8 and eosYearID = 2014

Select EmployeeID, 
count(case when DaysList = 'В' then 1 end) as [Выходных],
count(case when DaysList = 'О' then 1 end) as [Отпускных],
count(case when DaysList = 'Б' then 1 end) as [Больничных]
From @t
group by
 EmployeeID
order by
 EmployeeID
30 авг 14, 20:05    [16516427]     Ответить | Цитировать Сообщить модератору
 Re: Пожалуйста, помогите отпимизировать запрос по вычислению кол-ва выходных дней в графике  [new]
iap
Member

Откуда: Москва
Сообщений: 47052
alex_forw
не создавал представление ибо держать в нем миллион миллионов записей
Как это понимать?
30 авг 14, 21:08    [16516535]     Ответить | Цитировать Сообщить модератору
 Re: Пожалуйста, помогите отпимизировать запрос по вычислению кол-ва выходных дней в графике  [new]
invm
Member

Откуда: Москва
Сообщений: 9646
alex_forw
не создавал представление ибо держать в нем миллион миллионов записей
Обычные представления не содержат данных.
30 авг 14, 21:13    [16516542]     Ответить | Цитировать Сообщить модератору
 Re: Пожалуйста, помогите отпимизировать запрос по вычислению кол-ва выходных дней в графике  [new]
invm
Member

Откуда: Москва
Сообщений: 9646
aleks2
Что я вижу?!
Борец за эффективность снова предлагает неэффективные решения?
Ну что же, померяемся эффективностями. На 2000 версии.
+ Подготовка данных
use tempdb;
go

create table dbo.t (id int identity primary key, f1 int, f2 int, f3 int, f4 int, f5 int, f6 int, f7 int, f8 int, f9 int, f10 int);
go

insert into dbo.t
select top 1000000
 rand(checksum(newid())) * 100,
 rand(checksum(newid())) * 100,
 rand(checksum(newid())) * 100,
 rand(checksum(newid())) * 100,
 rand(checksum(newid())) * 100,
 rand(checksum(newid())) * 100,
 rand(checksum(newid())) * 100,
 rand(checksum(newid())) * 100,
 rand(checksum(newid())) * 100,
 rand(checksum(newid())) * 100
from
 master.dbo.spt_values a cross join
 master.dbo.spt_values b cross join
 master.dbo.spt_values c;
go

create view dbo.vt_unpivoted
as
select
 t.id,
 case n.n
  when 1 then t.f1
  when 2 then t.f2
  when 3 then t.f3
  when 4 then t.f4
  when 5 then t.f5
  when 6 then t.f6
  when 7 then t.f7
  when 8 then t.f8
  when 9 then t.f9
  when 10 then t.f10
 end as f
from
 dbo.t cross join
 (select 1 as n union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9 union all select 10) n
go

+ Эффективный вариант от aleks2
set statistics time on;
go

select count(c10), count(c20), count(c30) from
(
select
 id,
 (
  select count(*) from
  (
   select t.f1 as f union all select t.f2 union all select t.f3 union all select t.f4 union all select t.f5 union all
   select t.f6 union all select t.f7 union all select t.f8 union all select t.f9 union all select t.f10
  ) a
  where a.f = 10
 ) as c10,
 (
  select count(*) from
  (
   select t.f1 as f union all select t.f2 union all select t.f3 union all select t.f4 union all select t.f5 union all
   select t.f6 union all select t.f7 union all select t.f8 union all select t.f9 union all select t.f10
  ) a
  where a.f = 20
 ) as c20,
 (
  select count(*) from
  (
   select t.f1 as f union all select t.f2 union all select t.f3 union all select t.f4 union all select t.f5 union all
   select t.f6 union all select t.f7 union all select t.f8 union all select t.f9 union all select t.f10
  ) a
  where a.f = 30
 ) as c30
from
 dbo.t
where
 t.id % 10 = 0
) q
option
 (maxdop 1);

set statistics time off;
go

+ Неэффективный вариант от invm
set statistics time on;
go

select count(c10), count(c20), count(c30) from
(
select
 a.id,
 count(case when a.f = 10 then 1 end) as c10,
 count(case when a.f = 20 then 1 end) as c20,
 count(case when a.f = 30 then 1 end) as c30
from
 dbo.vt_unpivoted a
where
 a.id % 10 = 0
group by
 a.id
) q
option
 (maxdop 1);

set statistics time off;
go

Тайминги
Эффективный вариант от aleks2CPU time = 1935 ms, elapsed time = 1947 ms.
Неэффективный вариант от invmCPU time = 544 ms, elapsed time = 544 ms.


Наверное опять данные не такие...
30 авг 14, 21:35    [16516596]     Ответить | Цитировать Сообщить модератору
 Re: Пожалуйста, помогите отпимизировать запрос по вычислению кол-ва выходных дней в графике  [new]
invm
Member

Откуда: Москва
Сообщений: 9646
Планы выкладываю отдельно, ибо не влезло в одно сообщение.
+ Эффективный план от aleks2
Rows        Executes    StmtText                                                                                                                                                                                                              
----------- ----------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 1 select count(c10), count(c20), count(c30) from
(
select
id,
(
select count(*) from
(
select t.f1 as f union all select t.f2 union all select t.f3 union all select t.f4 union all select t.f5 union all
select t.f6 union all select t.f7 un 8 1 0 NULL NULL NULL NULL 1.0 NULL NULL NULL 12.855621 NULL NULL SELECT 0 NULL
1 1 |--Compute Scalar(DEFINE:([Expr1038]=Convert([Expr1056]), [Expr1039]=Convert([Expr1057]), [Expr1040]=Convert([Expr1058])))
1 1 |--Stream Aggregate(DEFINE:([Expr1056]=COUNT_BIG([Expr1011]), [Expr1057]=COUNT_BIG([Expr1023]), [Expr1058]=COUNT_BIG([Expr1035])))
100000 1 |--Compute Scalar(DEFINE:([Expr1011]=[Expr1011], [Expr1023]=[Expr1023], [Expr1035]=[Expr1035]))
100000 1 |--Nested Loops(Inner Join, OUTER REFERENCES:([t].[f10], [t].[f9], [t].[f8], [t].[f7], [t].[f6], [t].[f5], [t].[f4], [t].[f3], [t].[f2], [t].[f1]))
100000 1 |--Nested Loops(Inner Join, OUTER REFERENCES:([t].[f10], [t].[f9], [t].[f8], [t].[f7], [t].[f6], [t].[f5], [t].[f4], [t].[f3], [t].[f2], [t].[f1]))
100000 1 | |--Nested Loops(Inner Join, OUTER REFERENCES:([t].[f10], [t].[f9], [t].[f8], [t].[f7], [t].[f6], [t].[f5], [t].[f4], [t].[f3], [t].[f2], [t].[f1]))
100000 1 | | |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[t].[PK__t__0AD2A005]), WHERE:([t].[id]%10=0))
100000 100000 | | |--Hash Match(Cache, HASH:([t].[f10], [t].[f9], [t].[f8], [t].[f7], [t].[f6], [t].[f5], [t].[f4], [t].[f3], [t].[f2], [t].[f1]), RESIDUAL(((((([t].[f10]=[t].[f10] AND [t].[f9]=[t].[f9]) AND [t].[f8]=[t].[f8]) AND [t].[f7
100000 100000 | | |--Compute Scalar(DEFINE:([Expr1011]=Convert([Expr1053])))
100000 100000 | | |--Stream Aggregate(DEFINE:([Expr1053]=Count(*)))
9958 100000 | | |--Concatenation
1036 100000 | | |--Filter(WHERE:(STARTUP EXPR([t].[f1]=10)))
1036 1036 | | | |--Constant Scan
957 100000 | | |--Filter(WHERE:(STARTUP EXPR([t].[f2]=10)))
957 957 | | | |--Constant Scan
997 100000 | | |--Filter(WHERE:(STARTUP EXPR([t].[f3]=10)))
997 997 | | | |--Constant Scan
984 100000 | | |--Filter(WHERE:(STARTUP EXPR([t].[f4]=10)))
984 984 | | | |--Constant Scan
983 100000 | | |--Filter(WHERE:(STARTUP EXPR([t].[f5]=10)))
983 983 | | | |--Constant Scan
953 100000 | | |--Filter(WHERE:(STARTUP EXPR([t].[f6]=10)))
953 953 | | | |--Constant Scan
1018 100000 | | |--Filter(WHERE:(STARTUP EXPR([t].[f7]=10)))
1018 1018 | | | |--Constant Scan
984 100000 | | |--Filter(WHERE:(STARTUP EXPR([t].[f8]=10)))
984 984 | | | |--Constant Scan
997 100000 | | |--Filter(WHERE:(STARTUP EXPR([t].[f9]=10)))
997 997 | | | |--Constant Scan
1049 100000 | | |--Filter(WHERE:(STARTUP EXPR([t].[f10]=10)))
1049 1049 | | |--Constant Scan
100000 100000 | |--Hash Match(Cache, HASH:([t].[f10], [t].[f9], [t].[f8], [t].[f7], [t].[f6], [t].[f5], [t].[f4], [t].[f3], [t].[f2], [t].[f1]), RESIDUAL(((((([t].[f10]=[t].[f10] AND [t].[f9]=[t].[f9]) AND [t].[f8]=[t].[f8]) AND [t].[f7]=[t]
100000 100000 | |--Compute Scalar(DEFINE:([Expr1023]=Convert([Expr1054])))
100000 100000 | |--Stream Aggregate(DEFINE:([Expr1054]=Count(*)))
9965 100000 | |--Concatenation
959 100000 | |--Filter(WHERE:(STARTUP EXPR([t].[f1]=20)))
959 959 | | |--Constant Scan
1016 100000 | |--Filter(WHERE:(STARTUP EXPR([t].[f2]=20)))
1016 1016 | | |--Constant Scan
992 100000 | |--Filter(WHERE:(STARTUP EXPR([t].[f3]=20)))
992 992 | | |--Constant Scan
1041 100000 | |--Filter(WHERE:(STARTUP EXPR([t].[f4]=20)))
1041 1041 | | |--Constant Scan
992 100000 | |--Filter(WHERE:(STARTUP EXPR([t].[f5]=20)))
992 992 | | |--Constant Scan
1005 100000 | |--Filter(WHERE:(STARTUP EXPR([t].[f6]=20)))
1005 1005 | | |--Constant Scan
922 100000 | |--Filter(WHERE:(STARTUP EXPR([t].[f7]=20)))
922 922 | | |--Constant Scan
1042 100000 | |--Filter(WHERE:(STARTUP EXPR([t].[f8]=20)))
1042 1042 | | |--Constant Scan
966 100000 | |--Filter(WHERE:(STARTUP EXPR([t].[f9]=20)))
966 966 | | |--Constant Scan
1030 100000 | |--Filter(WHERE:(STARTUP EXPR([t].[f10]=20)))
1030 1030 | |--Constant Scan
100000 100000 |--Hash Match(Cache, HASH:([t].[f10], [t].[f9], [t].[f8], [t].[f7], [t].[f6], [t].[f5], [t].[f4], [t].[f3], [t].[f2], [t].[f1]), RESIDUAL(((((([t].[f10]=[t].[f10] AND [t].[f9]=[t].[f9]) AND [t].[f8]=[t].[f8]) AND [t].[f7]=[t].[f7]
100000 100000 |--Compute Scalar(DEFINE:([Expr1035]=Convert([Expr1055])))
100000 100000 |--Stream Aggregate(DEFINE:([Expr1055]=Count(*)))
9907 100000 |--Concatenation
1001 100000 |--Filter(WHERE:(STARTUP EXPR([t].[f1]=30)))
1001 1001 | |--Constant Scan
938 100000 |--Filter(WHERE:(STARTUP EXPR([t].[f2]=30)))
938 938 | |--Constant Scan
975 100000 |--Filter(WHERE:(STARTUP EXPR([t].[f3]=30)))
975 975 | |--Constant Scan
1009 100000 |--Filter(WHERE:(STARTUP EXPR([t].[f4]=30)))
1009 1009 | |--Constant Scan
1009 100000 |--Filter(WHERE:(STARTUP EXPR([t].[f5]=30)))
1009 1009 | |--Constant Scan
988 100000 |--Filter(WHERE:(STARTUP EXPR([t].[f6]=30)))
988 988 | |--Constant Scan
1016 100000 |--Filter(WHERE:(STARTUP EXPR([t].[f7]=30)))
1016 1016 | |--Constant Scan
1001 100000 |--Filter(WHERE:(STARTUP EXPR([t].[f8]=30)))
1001 1001 | |--Constant Scan
989 100000 |--Filter(WHERE:(STARTUP EXPR([t].[f9]=30)))
989 989 | |--Constant Scan
981 100000 |--Filter(WHERE:(STARTUP EXPR([t].[f10]=30)))
981 981 |--Constant Scan

+ Неэффективный план от invm
Rows        Executes    StmtText                                                                                                                                                                                                              
----------- ----------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 1 select count(c10), count(c20), count(c30) from
(
select
a.id,
count(case when a.f = 10 then 1 end) as c10,
count(case when a.f = 20 then 1 end) as c20,
count(case when a.f = 30 then 1 end) as c30
from
dbo.vt_unpivoted a
where
a.id % 10 = 0 9 1 0 NULL NULL NULL NULL 1.0 NULL NULL NULL 9.2204943 NULL NULL SELECT 0 NULL
1 1 |--Compute Scalar(DEFINE:([Expr1024]=Convert([Expr1042]), [Expr1025]=Convert([Expr1043]), [Expr1026]=Convert([Expr1044])))
1 1 |--Stream Aggregate(DEFINE:([Expr1042]=COUNT_BIG([Expr1021]), [Expr1043]=COUNT_BIG([Expr1022]), [Expr1044]=COUNT_BIG([Expr1023])))
100000 1 |--Compute Scalar(DEFINE:([Expr1021]=Convert([Expr1039]), [Expr1022]=Convert([Expr1040]), [Expr1023]=Convert([Expr1041])))
100000 1 |--Stream Aggregate(GROUP BY:([t].[id]) DEFINE:([Expr1039]=COUNT_BIG(If (If ([Union1020]=1) then [t].[f1] else If ([Union1020]=2) then [t].[f2] else If ([Union1020]=3) then [t].[f3] else If ([Union1020]=4) then [t].[f4] else If ([Union1020
1000000 1 |--Nested Loops(Inner Join)
100000 1 |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[t].[PK__t__0AD2A005]), WHERE:([t].[id]%10=0))
1000000 100000 |--Table Spool
10 1 |--Concatenation
1 1 |--Constant Scan
1 1 |--Constant Scan
1 1 |--Constant Scan
1 1 |--Constant Scan
1 1 |--Constant Scan
1 1 |--Constant Scan
1 1 |--Constant Scan
1 1 |--Constant Scan
1 1 |--Constant Scan
1 1 |--Constant Scan
30 авг 14, 21:54    [16516654]     Ответить | Цитировать Сообщить модератору
 Re: Пожалуйста, помогите отпимизировать запрос по вычислению кол-ва выходных дней в графике  [new]
invm
Member

Откуда: Москва
Сообщений: 9646
А если уж говорить об эффективности, применительно к задаче ТС, то
1.
alter table EmployeeOperatingSchedule add eosEncodedDaysData as cast(quotename(isnull(eosD01, '')) + ... + quotename(isnull(eosD31, '')) as varchar(8000));

2.
select
 eosEmployeeID as EmployeeID,
 (len(eosEncodedDaysData) - len(replace(eosEncodedDaysData, quotename('В'), ''))) / len(quotename('В')) as [Выходных],
 (len(eosEncodedDaysData) - len(replace(eosEncodedDaysData, quotename('О'), ''))) / len(quotename('О')) as [Отпускных]
from
 EmployeeOperatingSchedule
where
 eosMonthID = 8 and eosYearID = 2014
order by
 eosEmployeeID;
30 авг 14, 23:11    [16516805]     Ответить | Цитировать Сообщить модератору
 Re: Пожалуйста, помогите отпимизировать запрос по вычислению кол-ва выходных дней в графике  [new]
aleks2
Guest
invm
Планы выкладываю отдельно, ибо не влезло в одно сообщение.

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

ЗЫ: Ты и правда веришь, что чем план короче - тем оно эффективнее?
31 авг 14, 08:46    [16516995]     Ответить | Цитировать Сообщить модератору
 Re: Пожалуйста, помогите отпимизировать запрос по вычислению кол-ва выходных дней в графике  [new]
invm
Member

Откуда: Москва
Сообщений: 9646
aleks2
Как мне нравятся безграмотные борцы за эффективность!
Может я и безграмотен, но почему-то мой безграмотный запрос оказался эффективнее твоего. Наверное случайно.
aleks2
Которые свято веруют в Великий План и в то, что лишние операции соединения, размножения строк и группировки ничего не требуют.
Ну да, всем же очевидно, глядя на планы, что в твоем запросе нет ничего лишнего и аналогичные операции ничего не требуют.
aleks2
Ты и правда веришь, что чем план короче - тем оно эффективнее?
Планы - не объект веры, планы - объект для анализа. Именно для этого они и были опубликованы. Чтобы интересующиеся могли выяснить, почему твой вариант оказался в 4 раза менее эффективен моего.
Если ты этого не понял, то большой вопрос кто из нас более безграмотен.
31 авг 14, 10:45    [16517035]     Ответить | Цитировать Сообщить модератору
 Re: Пожалуйста, помогите отпимизировать запрос по вычислению кол-ва выходных дней в графике  [new]
alex_forw
Member

Откуда:
Сообщений: 23
invm
alex_forw
не создавал представление ибо держать в нем миллион миллионов записей
Обычные представления не содержат данных.



Да, я знаю, что представление, это по-сути своей таблица-запрос которая выдает данные из других таблиц ничего в себе не храня, по-этому и написал держать, а не ХРАНИТЬ. А написал вообще потому, что невнимательно посмотрел код ведь там были и месяц и год для отсекания лишнего (фраза про миллион миллионов). В общем - лапухнулся...

Смотрю, тут целая баталия разыгралась между спецами:) Сейчас покопаюсь и еще один вариант (с add eosEncodedDaysData) опробую

Большое всем спасибо за участие, вынес из обсуждения новые для себя вещи :)
31 авг 14, 13:24    [16517202]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить