четверг, 20 декабря 2012 г.

row_number vs with. Практика.

T-SQL.
Есть две даты как параметры, между ними не бывает большого диапазона, ну скажем не более месяца...


Задача: запросом вернуть список дат между двумя заданными, вспомогательных табличек нет.

Два варианта.
1. Используя row_number




declare @d1 datetime, @d2 datetime, @li int

set @d1 ='20121201'
set @d2='20121212'

set @li=datediff(d, @d1, @d2)

select top(@li) dateadd(d, (row_number() over(order by s1.id))-1, @d1)
from sys.sysobjects s1


2. Используя WITH


declare @d1 datetime, @d2 DATETIME, @di1 INT, @di2 INT

set @d1 ='20121201';
set @d2='20121212';
SET @di1 = CAST (@d1 AS INT);
SET @di2 = CAST (@d2 AS INT);

WITH sq(num) AS 
(
 SELECT CAST(@di1 AS DATETIME)
 UNION ALL
    SELECT CAST(num + 1 AS DATETIME) FROM sq WHERE num < @di2
)
SELECT * FROM sq



Второй вариант работает чуть быстрее (милисекунды) чем первый на малом диапазоне, поэтому на малом диапазоне выбирайте, что душе угодно.
А вот на больших диапазонах выигрыш второго варианта существенный.
Потестируйте -)


среда, 18 апреля 2012 г.

DISTINCT

Абсолютно одинаковые планы запросов на MS SQL Express,  но версия с DISTINCT будет отличаться на MS SQL Enterprise. Потому что в план запроса включится Parallel процесс.

SELECT COUNT(DISTINCT Color)
FROM [Production].[Product] pp
WHERE Color is not null

select COUNT(*)
from (
SELECT Color
FROM [Production].[Product] pp
where Color is not null
group by pp.Color) a