[英]select based on calculated value, optimization
我需要在其他領域中選擇客戶在購買特定品牌產品等時的年齡,例如客戶在30到50歲之間。我寫了這個查詢(getAge只使用DATEDIFF來以年為單位返回年齡)
SELECT DISTINCT customers.FirstName, customers.LastName,
products.ProductName,
dbo.getAge(customers.BirthDate,sales.Datekey)
AS Age_when_buying
FROM sales
INNER JOIN dates ON sales.Datekey=dates.Datekey
INNER JOIN customers ON sales.CustomerKey=customers.CustomerKey
INNER JOIN products ON sales.ProductKey=products.ProductKey
INNER JOIN stores ON sales.StoreKey=stores.StoreKey
WHERE stores.StoreName = 'DribleCom Europe Online Store' AND
products.BrandName = 'Proseware' AND
dbo.getAge(customers.BirthDate, sales.Datekey) >= 30 AND
dbo.getAge(customers.BirthDate, sales.Datekey) <=50
它工作,但我計算年齡三次。我試圖將age_when_buying分配給一個變量,但它沒有工作。我接下來的想法是使用光標,但我覺得有一個更簡單的方法,我失蹤。問題是:這是解決這個問題的合適方式或者我的選擇是什么?
假設您只需要應用有限數量的過濾器,則可以使用公用表表達式重新構建查詢。
我個人覺得在一個地方看到所有連接更容易,而過濾器在底部類似地組合在一起...
WITH CTE AS(
select customers.FirstName
, customers.LastName
, dbo.getAge(customers.BirthDate,sales.Datekey) AS Age_when_buying
, sales.StoreName
, products.BrandName
, products.ProductName
from sales
INNER JOIN customers on sales.CustomerKey=customers.CustomerKey
INNER JOIN products ON sales.ProductKey = products.ProductKey
INNER JOIN stores ON sales.StoreKey = stores.StoreKey
)
SELECT DISTINCT FirstName, LastName, ProductName, Age_when_buying
FROM CTE
WHERE StoreName = 'DribleCom Europe Online Store'
AND BrandName = 'Proseware'
AND Age_when_buying BETWEEN 30 AND 50
您應該使用Cross Apply。
SELECT DISTINCT customers.FirstName, customers.LastName,
products.ProductName,
age.age AS Age_when_buying
FROM sales
INNER JOIN dates ON sales.Datekey=dates.Datekey
INNER JOIN customers ON sales.CustomerKey=customers.CustomerKey
INNER JOIN products ON sales.ProductKey=products.ProductKey
INNER JOIN stores ON sales.StoreKey=stores.StoreKey
CROSS APPLY
(select dbo.getAge(customers.BirthDate, sales.Datekey) as age) age
WHERE stores.StoreName = 'DribleCom Europe Online Store' AND
products.BrandName = 'Proseware' AND
age.age >= 30 AND
age.age <=50
您可以使用WITH
子句:
WITH Customers_Info (CustomerFirstName, CustomerLastName, CustomerKey, AgeWhenBuying)
AS
(
SELECT customers.FirtName,
customers.LastName,
CustomerKey
dbo.getAge(customers.BirthDate, sales.DateKey) As AgeWhenBuying
FROM customers
JOIN sale USING(CustomerKey)
)
SELECT FirstName,
LastName,
products.ProductName,
Customers_Info.AgeWhenBuying
FROM Customers_Info
JOIN sale USING(CustomerKey)
JOIN products USING(ProductKey)
JOIN stores USING(StoreKey)
WHERE stores.StoreName = 'DribleCom Europe Online Store'
AND products.BrandName = 'Proseware'
AND Customers_Info.AgeWhenBuying >= 30
AND Customers_Info.AgeWhenBuying <= 50;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.