Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Селективность по Dan Tow (книга - “ SQL Turning”)  [new]
uncle_max
Member

Откуда:
Сообщений: 70
Добрый день,
Книга – гениальная, но после прочтения половины я впал в полный ступор. Подскажите, как с Oracle перевести на MS SQL след. запрос для вычисления вероятностной селективности.
здесь кусочек теории:
Each last name has a selectivity of n(i)/C, where n(i) is the count of rows with the ith nonnull
last name and C is the count of all rows in the table. If choosing any last name were equally probable,
you could just average n(i)/C over all the last names. That average would equal one over the number
of distinct names. However, the probability of searching on a last name in this scenario is n(i)/C',
where C' is the count of rows having nonnull last names. Therefore, you really need the sum of the
selectivities times the probability of seeing each selectivity—i.e., the sum of (n(i)/C') x (n(i)/C)
—over all last names. Since C' is also the sum of the individual n(i) values, you can compute the filter
selectivity in SQL as follows:

а вот и сам запрос, который генерит ошибку под MS SQL:

SELECT SUM(COUNT(Last_Name)*COUNT(Last_Name))/
        (SUM(COUNT(Last_Name))*SUM(COUNT(*))) 
FROM Customers GROUP BY Last_Name

Server: Msg 130, Level 15, State 1, Line 1
Cannot perform an aggregate function on an expression containing an aggregate or a subquery.


Заранее спасибо,
Max
11 дек 09, 07:24    [8050248]     Ответить | Цитировать Сообщить модератору
 Re: Селективность по Dan Tow (книга - “ SQL Turning”)  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
uncle_max,

а в Oracle это нормально считается?
Что, собственно говоря, должно дать SUM(COUNT(*)) по-Вашему?
11 дек 09, 09:44    [8050627]     Ответить | Цитировать Сообщить модератору
 Re: Селективность по Dan Tow (книга - “ SQL Turning”)  [new]
Glamorama
Member

Откуда:
Сообщений: 152
что-то типа этого получается
SELECT
	SUM([n(i)]*[n(i)])/(SUM([C_])*SUM([C]))
FROM(
	SELECT 
		A.LastName AS [i]
		,CAST(COUNT(*) AS FLOAT) AS  [n(i)]
		,CAST(B.[C] AS FLOAT) AS [C]
		,CAST(B.[C"] AS FLOAT) AS [C_]
	FROM Customers A
	JOIN (SELECT COUNT(*) AS [C],SUM(CASE WHEN LastName IS NULL THEN 0 ELSE 1 END) AS [C_] FROM Customers) B ON 1=1
	WHERE LastName IS NOT NULL
	GROUP BY
		A.LastName
		,B.[C]
		,B.[C_]
	) A

Если я правильно понимаю, то в Oracle
SELECT SUM(COUNT(*)) FROM Customers GROUP BY LastName
равносильно в MS SQL
SELECT SUM(S) FROM ( SELECT COUNT(*)  S FROM Customers GROUP BY LastName) A
11 дек 09, 10:13    [8050789]     Ответить | Цитировать Сообщить модератору
 Re: Селективность по Dan Tow (книга - “ SQL Turning”)  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Glamorama
Если я правильно понимаю, то в Oracle
SELECT SUM(COUNT(*)) FROM Customers GROUP BY LastName
равносильно в MS SQL
SELECT SUM(S) FROM ( SELECT COUNT(*)  S FROM Customers GROUP BY LastName) A
То есть GROUP BY относится к COUNT(*), а не к SUM?
11 дек 09, 10:27    [8050881]     Ответить | Цитировать Сообщить модератору
 Re: Селективность по Dan Tow (книга - “ SQL Turning”)  [new]
Glamorama
Member

Откуда:
Сообщений: 152
да
11 дек 09, 11:04    [8051292]     Ответить | Цитировать Сообщить модератору
 Re: Селективность по Dan Tow (книга - “ SQL Turning”)  [new]
Glory
Member

Откуда:
Сообщений: 104760
SELECT COUNT(DISTINCT LastName) FROM Customers не проще будет ?
11 дек 09, 11:06    [8051321]     Ответить | Цитировать Сообщить модератору
 Re: Селективность по Dan Tow (книга - “ SQL Turning”)  [new]
uncle_max
Member

Откуда:
Сообщений: 70
Glamorama

SELECT
	SUM([n(i)]*[n(i)])/(SUM([C_])*SUM([C]))
FROM(
	SELECT 
		A.LastName AS [i]
		,CAST(COUNT(*) AS FLOAT) AS  [n(i)]
		,CAST(B.[C] AS FLOAT) AS [C]
		,CAST(B.[C"] AS FLOAT) AS [C_]
	FROM Customers A
	JOIN (SELECT COUNT(*) AS [C],SUM(CASE WHEN LastName IS NULL THEN 0 ELSE 1 END) AS [C_] FROM Customers) B ON 1=1
	WHERE LastName IS NOT NULL
	GROUP BY
		A.LastName
		,B.[C]
		,B.[C_]
	) A


Glamorama, спасибо большое за пример. Единственное что - опечатка вкралась
CAST(B.[C"] AS FLOAT) AS [C_] должен быть CAST(B.[C_] AS FLOAT) AS [C_] 


Буду продолжать разбираться
14 дек 09, 01:23    [8061145]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить