2009-10-15 7 views
0

나는 월별 청구 레코드 데이터가있는 테이블을 가지고 있습니다. 따라서 Customer 1234은 1 월/2 월에 청구되었고 Customer 2345은 1 월/2 월/3 월이었습니다. 월간 결제주기를 동시에 표시하려면 어떻게 그룹화해야합니까?SQL 여러 개의 쿼리 중에서 하나의 쿼리를 만드는 방법

Customer 1234 was billed for 2 months Concurrent 
Customer 2345 was billed for 3 months Concurrent 
Customer 3456 was billed for 4 months Non-Concurrent 

어떤 제안 :뿐만 아니라 너무 Customer 3456 필요 2월/APL/6월/8월

SELECT custName, month, billed, count(*) as Tally 
FROM db_name 
WHERE 
GROUP BY 

결과를 청구하고, 비 동시 청구 개월이 필요합니다?

+1

귀하의 설명에서, 동시성보다는 오히려 인접성을 의미할까요? 나는. "동시에"가 아니라 "다음 달에"? –

+0

RDBMS 란 무엇입니까? – cmsjr

+0

도 월, 숫자 또는 이름으로 저장됩니까? – cmsjr

답변

1

, 첫 번째와 마지막 법안 사이의 개월 수를 계산하는 DATEDIFF를 사용할 수 있습니다. 경과 개월 수가 청구서의 총 수와 같으면 지폐는 연속됩니다.

select 
'Customer ' + custname + ' was billed for ' + 
cast(count(*) as varchar) + ' months ' + 
case 
    when datediff(month,min(billdate),max(billdate))+1 = count(*) 
    then 'Concurrent' 
    else 'Non-Concurrent' 
end 
from @billing 
where billed = 1 
group by custname 

결제 월을 정수로 저장하는 경우 DATEDIFF를 사용하는 대신 뺄 수 있습니다. WHEN 행을 다음으로 대체하십시오.

when max(billdate)-min(billdate)+1 = count(*) 

그러나이 경우 나는 당신이 어떻게 년을 구별하는지 궁금합니다.

+0

덕분에 도움이되었습니다. –

+0

한 달에 하나의 청구서가 있습니까?나는 그것을 완전히 놓쳤다. –

+0

샘플 데이터를 기반으로 가정에서 잘못된 경우 "from @billing"을 "from (선택 custname, 청구 그룹 by bill, billdate) sub"로 대체 할 수 있습니다. – Andomar

0

방법 :

SELECT custName, month, count(*) as tally 
from billing 
where billed = 1 
group by custName, month 
+0

이것은 내가 필요로하는 것이지만 여러 사례가 필요하다고 생각하는 조건이 필요합니다. 감사합니다. –

1

만약 달 모든 순서에 있었다, 우리는 다음 최소 (월) + 수 (회 청구) 특정 연도에 대한 우리의 검색을 제한하고 - 일해야 = 최대 (달). 달이 날짜 필드로 저장되어있는 경우

declare @billing table(Custname varchar(10), month int, billed bit) 

insert into @billing values (1234, 1, 1) 
insert into @billing values (1234, 2, 1) 
insert into @billing values (2345, 3, 1) 
insert into @billing values (2345, 4, 1) 
insert into @billing values (2345, 5, 1) 
insert into @billing values (3456, 1, 1) 
insert into @billing values (3456, 3, 1) 
insert into @billing values (3456, 9, 1) 
insert into @billing values (3456, 10, 1) 

Select CustName, Count(1) as MonthsBilled, 
Case 
    when Min(Month) + Count(1) - 1 = Max(Month) 
    then 1 
    else 0 
end Concurrent 
From @billing 
where Billed = 1 
Group by CustName 

Cust Months Concurrent 
1234 2   1 
2345 3   1 
3456 4   0 
+0

감사합니다. –

1

제안 사항은 동일한 달에 두 번 이상 고객에게 청구하지 않는다는 가정하에 작성되었습니다. 이것이 안전한 가정이 아니라면 다른 접근 방식이 필요합니다. 그럴 경우 알려주십시오.

+1

좋은 지적, 그룹으로 해결 될 수 있음 by 하위 쿼리 – Andomar

+0

당신 말이 맞아요.하지만 그들이 청구되는 한 달에 한 번 이상 요금이 청구되는지는 알 필요가 없습니다. GROUP BY가이 상황을 처리 할 것이라고 생각했습니다. 주어진 시간 동안 일부 비즈니스 분석 분석을위한 쿼리. –

0

당신은 당신이 사용중인 데이터베이스 (방법 월이 저장되어 같은) 몇 가지 중요한 정보를 왼쪽, 그러나 여기 당신이 시작할 수있는 논리적 인 접근 방식 : 여기에 월 가정

CREATE VIEW CustomerBilledInMonth (CustName, Month, AmountBilled, ContinuousFlag) AS 
    SELECT CustName, Month, SUM(AmountBilled), 'Noncontinuous' 
    FROM BillingTable BT1 
    WHERE NOT EXISTS 
    (SELECT * FROM BillingTable BT2 WHERE BT2.CustName = BT1.CustName AND BT2.Month = BT1.Month - 1) 
    GROUP BY CustName, Month 
    UNION 
    SELECT CustName, Month, SUM(AmountBilled), 'Continuous' 
    FROM BillingTable BT1 
    WHERE EXISTS 
    (SELECT * FROM BillingTable BT2 WHERE BT2.CustName = BT1.CustName AND BT2.Month = BT1.Month - 1) 
    GROUP BY CustName, Month 

가 연속이다 정수 필드가 시스템의 첫 번째 가능한 달에서 1 씩 증가하면 매월 각 고객의 청구서를 요약하고 고객에게 청구 된 달이 지난 달에 '연속'을 포함하는 추가 플래그와 고객에게 청구되지 않은 달이 지난 달의 경우 '비 연속'으로 표시됩니다. 그런 다음

:

SELECT CustName, LISTOF(Month), SUM(AmountBilled), MAX(ContinuousFlag) 
    FROM CustomerBilledInMonth GROUP BY CustName 

더 이하 (LISTOF 당신이 사용하고있는 정확한 데이터베이스에 의존 COALESCE 형 기능의 일종입니다) 당신이 원하는 걸 줄 것입니다.

+1

이 방법은 첫 번째 달을 항상 비 연속적으로 나열합니다. – Andomar

+0

네, 그렇습니다. 내 허락없는 가정 중보기 정의 또는 두 번째 궁극적 인 SELECT 쿼리를 데이터베이스의 전체 개월 미만으로 제한 할 수 있습니다. –

+0

그래, 이전에 UNION ALL과 SUB SELECTS를 시도했지만 필요한 결과를 얻고 있었지만 CASE 문이 내가 결국 원하는 것이 더 나은 방법이라고 생각합니다. 입력 해 주셔서 감사합니다. –

관련 문제