簡體   English   中英

根據計算值進行選擇,優化

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM