[英]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.