2017-11-16 14 views
1

私はこの問題を回避しようとしています。私は、私たちのデータベースにリピート顧客を示すレポートを作成するように頼まれました。同じ日に複数の購入をしたお客様は、1をカウントします。

特定の日付に複数の注文がある顧客は、1とカウントされます。 次に購入日が1日以上ある場合は、リピート顧客としてカウントされます。

ここで検索すると、特定の購入日に1件以上購入した顧客を検索するための検索結果が見つかりました。

SELECT DISTINCT s.[CustomerName], s.PurchaseDate 

FROM Reports.vw_Repeat s WHERE s.PurchaseDate <> ''  

GROUP BY s.[CustomerName] , cast(s.PurchaseDate as date) 

HAVING COUNT(*) > 1; 

このMSSQLコードは、同じ日に1以上購入した顧客を示すことによって、それが必要のように動作します。 私の問題は、最良のアプローチは、これを別のクエリに結合することです(これは私が助けが必要なところです)。それは、複数の購入を持つ顧客が返される完全なリピート顧客リストを示しています。

私はMSSQLを使用しています。どんな助けでも大歓迎です。

+0

他のクエリはどこにありますか? – Sami

+0

申し訳ありませんが、質問が書き込まれませんでした。私は、私がやろうとしていることを完了するために、最初のクエリを別のクエリに含める必要があると仮定しました。私はまだこれに新しいですし、2番目のクエリを取るための最善のルートを知らなかった。 –

+0

distinctを削除すると、そのクエリでは何も役に立ちません –

答えて

0

まずはお手伝いいただき、ありがとうございます。 @ MaxSzczurekはテーブル値関数を使用することを提案しました。これをさらに調べた後、最初に一時テーブルを使用して、各顧客のDISTINCT購入日を取得しました。私はそれを別の一時テーブルにロードしました。メインテーブルに右にジョインしました。これは私が探していた結果をもたらしました。その少し(たくさんの)醜いが、それは動作します。

0

パラメータをクエリに渡して結果を結合する場合は、これがテーブル値関数の対象です。あなたがそれに参加するときは、INNER JOINまたはLEFT JOINの代わりにCROSS APPLYまたはOUTER APPLYを使用します。

また、私はこれは言うまでもないと思うが、PurchaseDateが空であるかどうかをチェックする場合:

WHERE s.PurchaseDate <> '' 

が問題だろう...それはそれは(はい?)の代わりに日時のvarchar型のフィールドの意味NULL値を処理しません。少なくとも、それをISNULL(s.PurchaseDate、 '')< ''と置き換えることができます。実際にdatetimeの場合は、<> ''の代わりにIS NOT NULLを使用してください。

は(私は回答者を支援するためにSQLのポストにこれらを追加することをお勧めします。サンプルデータとDDL文を追加して編集しました。また、私は理由クエリ内の文字列を比較するのではなく、日時のpurchasedate varchar型を作った。)

https://technet.microsoft.com/en-us/library/ms191165(v=sql.105).aspx

CREATE TABLE company (company_name VARCHAR(25)) 
INSERT INTO company VALUES ('Company1'), ('Company2') 

CREATE TABLE vw_repeat (customername VARCHAR(25), purchasedate VARCHAR(25), company VARCHAR(25)) 
INSERT INTO vw_repeat VALUES ('Cust1', '11/16/2017', 'Company1') 
INSERT INTO vw_repeat VALUES ('Cust1', '11/16/2017', 'Company1') 
INSERT INTO vw_repeat VALUES ('Cust2', '11/16/2017', 'Company2') 

CREATE FUNCTION [dbo].tf_customers 
(
    @company varchar(25)  
) 
RETURNS TABLE AS RETURN 
(
    SELECT s.[CustomerName], cast(s.PurchaseDate as date) PurchaseDate 
    FROM vw_Repeat s 
    WHERE s.PurchaseDate <> '' AND s.Company = @company 
    GROUP BY s.[CustomerName] , cast(s.PurchaseDate as date) 
    HAVING COUNT(*) > 1 
) 
GO 

SELECT * 
FROM company c 
CROSS APPLY tf_customers(c.company_name) 
+0

優秀!私はすぐにこれを試してみるつもりです。 –

+0

distinctを削除すると、そのクエリには何も役に立ちません.... 'group by'は何をしますか? (行をユニークにする) "distinct"は何をするのですか? (行を一意にする)が最初に行われますか? (グループ化する)..... –

+0

@MaxSzczurekは「distinct」の削除をお勧めします –

0

あなたが近くにいる、あなたは1明確な購入日以上のものを持っている顧客のみが含まれるようにしたいので、あなたのhaving句にdistinctを移動する必要があります。

また、count distinctが同じグループに属している必要があるため、顧客IDでグループ化する必要があります。

SELECT s.[CustomerName], COUNT(distinct cast(s.PurchaseDate as date)) 
FROM Reports.vw_Repeat s WHERE s.PurchaseDate <> ''  
GROUP BY s.[CustomerName] 
HAVING COUNT(distinct cast(s.PurchaseDate as date)) > 1; 
+0

私はこれを試して、0行も返しました。上の質問で私が持っているクエリは、行を返します。あなたの例は有望であるようでした。 –

+0

'Select CustomerName、cast(s.PurchaseDate as date)'のサンプルデータを表示できますか?キャストが正しく機能しているのだろうかと思う。 – FuzzyTree

+0

返されるサンプルデータがある。顧客名はvw_Repeatのzipcodeと連結されています。でも、私は顧客の名前を編集した:XXXX - 95688 \t 2016年1月13日 XXXX - 91773 \t 2016年2月1日 XXXX - 29201 \t 2016年2月17日 XXXX - 72730 \t 2016年3月25日 XXXX - 30330 \t 2016-03-30 –

関連する問題