2017-06-07 29 views
-1

我有具有結構的shopware數據庫:MySQL查詢不回來 - 性能增強?

s_articles: all products 
id | name | mode 

s_order: all orders 
id | ordertime | userId | status 

s_order_details: all line items for an order 
id | orderId | articleId 

現在我要實現以下目標:我想現在有多少用戶購買了在過去的90天產品,買同樣的產品也早比過去90天。

我這樣做:我得到所有的文章,然後我得到所有在過去90天之前買過文章"boughtBefore90"的客戶,然後我有另一個子選擇,在那裏我收集所有的在過去的90天內購買了該產品的用戶,並在此之前購買了該產品,並將其保存在"boughtLast90"中。

然後我計算保留率。這適用於一種產品,但不適用於整個物品數據庫。有沒有什麼辦法可以寫出更好的性能的SQL?

我的查詢看起來是這樣的:

select articleId, articleName, boughtBefore90, boughtLast90, boughtLast90/boughtBefore90 as 'retention' 
FROM 

(select 
    s_articles.id as 'articleId', 
    s_articles.name as 'articleName', 
    (select count(*) 
     FROM s_order_details as s_order_details_2 
     join s_order as s_order_2 on s_order_2.Id = s_order_details_2.orderId 
     where s_order_details_2.articleId = s_articles.id 
     and (s_order_2.status = 0 or s_order_2.status = 2) 
     and s_order_2.ordertime > '2017-01-01 00:00:00' 
     and s_order_2.ordertime < '2017-03-09 23:59:59' 
    ) as 'boughtBefore90', 
    (select count(*) from s_order_details as s_order_details_3 
     join s_order as s_order_3 on s_order_3.id = s_order_details_3.orderId 
     where s_order_3.ordertime > '2017-03-10 00:00:00' 
     and s_order_3.ordertime < '2017-06-07 23:59:59' 
     and s_order_details_3.articleId = s_articles.id 
     and (s_order_3.status = 0 or s_order_3.status = 2) 
     AND s_order_3.userId = (
      select DISTINCT(s_order_4.userId) from s_order_details as s_order_details_4 
      join s_order as s_order_4 on s_order_4.id = s_order_details_4.orderId 
      where s_order_4.ordertime > '2017-01-01 00:00:00' 
      and s_order_4.ordertime < '2017-03-09 23:59:59' 
      and s_order_details_4.articleId = s_articles.id 
      and s_order_3.userId = s_order_4.userId 
      and (s_order_4.status = 0 or s_order_4.status = 2)) 
    ) as 'boughtLast90' 
    from 
    s_articles 
    join s_order_details on s_order_details.articleID = s_articles.id 
    join s_order on s_order.id = s_order_details.orderId 
    WHERE s_articles.mode = 0 
    AND s_order_details.modus = 0 
    AND (s_order.status = 2 or s_order.status = 0) 
    group by s_articles.id) as resulttable; 

謝謝!

+0

請參閱:[爲什麼我應該爲我認爲是非常簡單的SQL查詢提供一個MCVE?](https://meta.stackoverflow.com/questions/333952/why-should-i-provide-an -mcve-for-what-looks-to-the-a-very-simple-sql-query) – Strawberry

回答

0

這似乎是一個非常簡單的查詢。這是客戶和物品清單:

select o.customerid, od.articleid 
from s_orders o join 
    s_order_details od 
    on od.orderid = o.id 
group by o.customerid, od.articleid 
having max(o.ordertime) > curdate() - interval 90 days and 
     min(o.ordertime) <= curdate() - interval 90 days; 

如果你想有一個數,以此作爲一個子查詢和使用任何count(*)(客戶/條對)或count(distinct customerid)(客戶數量)。

+0

感謝您的快速回復。所以這個查詢爲我提供了問題的最終結果,即在過去的90天以及之前有多少客戶購買了這篇文章。但是現在我需要的是90天之前購買它的人數,並將其分配到結果中。我不能在這裏使用兩個子查詢,因爲那麼s_articles.id在子選擇中是未知的。我怎樣才能做到這一點? – Torben

+0

「我想現在有多少用戶在過去90天內購買了同樣產品的產品,這些產品也比過去90天早。」 –