0

顧客テーブルと、顧客に関連付けられた営業活動 (電話、電子メールなど) 用の別のテーブルがあります。私が知る必要があるのは、たとえば、過去 30 日間に (活動なしで) 連絡を受けていない顧客はどれかということです。

これが私がやろうとしていることです:

SELECT crm_customers.id, crm_ customers.companyname
FROM crm_ customers 
LEFT JOIN crm_activities on crm_customers.id = crm_ activities. Customerid
WHERE crm_ activities.createddate < (getDate() – 30)

問題は、最近のアクティビティがある場合でも、30 日より古いアクティビティを持つ顧客を返すことです。過去 30 日間に販売活動を行っていない顧客のみを取得する必要があります。ご協力ありがとうございます

4

2 に答える 2

0
SELECT crm_customers.id, crm_customers.companyname
FROM crm_customers 
LEFT JOIN crm_activities 
  on crm_customers.id = crm_activities.Customerid
 and DATEDIFF(DD, crm_activities.createddate, getdate()) < 30
where crm_activities.Customerid is null

これは、結合の条件が where の条件と異なる場合です。

速度のために、サブクエリを介した結合が疑われます。これにより、クエリ オプティマイザが最適化するためのオプションが増えます。個別は必要ありません。crm_activities.Customerid がインデックス化されていると仮定します。これはインデックスに参加しています。サブクエリでは、インデックスを使用してリストを作成しますが、サブクエリの出力にはインデックスが付けられません。

あなたのデータに依存します。テストする大きなテーブルがありました。

クエリ プランは異なります。

ループ結合ではデッドヒートだった ハッシュ結合では 2 倍の速さ マージ結合では 10 倍の速さ

誰も除外されない場合、それはデッド ヒートになります。
それが表示されるのは、多くの人が除外された場合です (過去 30 年間に連絡があった場合)。

于 2012-10-09T18:05:48.480 に答える
0

これはあなたを助けるかもしれません:

select 
    cust.id, cust.compayname
from
    crm_customers as cust
    left join (
        select 
            * 
        from 
            crm_activities 
        where 
            createddate >= (getDate() - 30)
    ) as act on cust.id = act.customerId
where
    act.customerId is null

このようにして、過去 30 日以内に活動を行ったすべての顧客を除外します。


次のようにして、これをもう少しクリーンアップすることができます。

select 
    cust.id, cust.compayname
from
    crm_customers as cust
    left join (
        select distinct 
            customerId 
        from 
            crm_activities where createddate >= (getDate() - 30)
    ) as act on cust.id = act.customerId
where
    act.customerId is null

基本的な考え方は同じです... 唯一のことは、この 2 番目のオプションは、アクティビティを含む顧客の ID を返すことだけです。whereこれで外節を最適化できると思いますが、サブクエリでのパフォーマンスに影響を与える可能性があります(フリーランチはありません)

于 2012-10-09T17:38:45.593 に答える