根据计算值进行选择,优化

时间:2015-04-24 15:48:08

标签: sql sql-server database performance

我需要在其他领域中选择客户在购买特定品牌产品等时的年龄,例如客户在30到50岁之间。我写了这个查询(getAge just使用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分配给一个变量,但它没有工作。我接下来的想法是使用光标但我觉得有一个更简单的方式我遗失。问题是:哪种方法可以解决这个问题或者我的选择是什么?

3 个答案:

答案 0 :(得分:4)

假设您只想申请数量有限的过滤器,可以使用Common Table Expression重新构建查询。

我个人觉得在一个地方看到所有连接更容易,而过滤器在底部类似地组合在一起......

a 
b 
c 
d 
e 
f

答案 1 :(得分:2)

您应该使用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

答案 2 :(得分:2)

您可以使用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;