2017-11-16 27 views
1

이 문제를 해결하기 위해 노력하고 있습니다. 나는 우리의 데이터베이스에 반복 고객을 보여주는 보고서를 작성하라는 요청을 받았습니다.반복 같은 날에 여러 번 구매 한 고객은 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 코드는 동일한 날짜에 2 번 이상 구입 한 고객을 표시해야하는 것처럼 작동합니다. 내 문제는 무엇이 최선의 접근 방식이 다른 쿼리 (여기에 내가 도움이 필요합니다)에 가입하면 하나 이상의 구매 고객이 반환됩니다 완전한 반복 고객 목록을 보여줍니다.

MSSQL을 사용 중입니다. 어떤 도움이라도 대단히 감사하겠습니다.

+0

다른 쿼리는 어디에 있습니까? – Sami

+0

죄송합니다. 질의를 작성하지 않았습니다. 나는 내가하려고하는 것을 완료하기 위해 다른 쿼리와 함께 첫 번째 쿼리를 포함해야한다고 생각했다. 나는 아직이 새로운이며 두 번째 쿼리를 취할 수있는 최상의 경로를 몰랐다. –

+0

distinct를 제거하면 해당 쿼리에서 아무런 도움이되지 않습니다. –

답변

0

도움을 주신 모든 분들께 감사드립니다. @ MaxSzczurek는 테이블 반환 함수를 사용하도록 제안했습니다. 이 부분을 자세히 살펴본 후에는 임시 테이블을 사용하여 각 고객에 대한 DISTINCT 구매 날짜를 얻었습니다. 그런 다음 다른 임시 테이블에로드 한 다음 기본 테이블에 올바르게 조인했습니다. 이것은 나에게 내가 찾던 결과를 주었다. 그것의 조금 (많이) 추한,하지만 작동합니다.

0

매개 변수를 쿼리에 전달하고 결과를 조인하려면 테이블 반환 함수를 사용해야합니다. 귀하가 가입 할 때, 귀하는 내부 결합 또는 좌측 결합 대신에 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

Excellent!나는 바로 이것을 시도 할 것이다. –

+0

distinct를 제거하면, 그 쿼리에서 아무런 도움이되지 않습니다 ....'group by'은 무엇을합니까? (행을 고유하게) "별개"는 무엇을합니까? (행을 고유하게 만드십시오) 먼저 수행됩니까? ..... (그룹화하여) ..... –

+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 - 91,773 \t 2016년 2월 1일 XXXX - 29,201 \t 2016년 2월 17일 XXXX - 72,730 \t 2016년 3월 25일 XXXX - 30330 \t 2016-03-30 –