2009-10-15 112 views
0

我有一張表,其中包含每月的賬單記錄數據。所以說1月/ 2月收費Customer 1234,1月/ 2月/ 3月收帳Customer 2345。如何將這些分組顯示給我一個並行的每月結算週期。但是,還需要有非併發紅嘴個月,所以Customer 3456被標榜需要二月/ APL /月/ 8SQL如何使多個查詢中的一個查詢

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

結果:

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 

有什麼建議?

+1

從你的描述,而不是併發,你可能意味着連續?即不是「同時」,而是「在接下來的幾個月」? – 2009-10-15 20:32:05

+0

你的RDBMS是什麼? – cmsjr 2009-10-15 20:35:50

+0

另外,月份如何儲存,數字或名稱? – cmsjr 2009-10-15 20:38:28

回答

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

感謝這幫了很多 – 2009-10-16 12:14:25

+0

每月只有一個賬單?我完全錯過了。 – 2009-10-16 13:30:00

+0

假設根據樣本數據,如果假設不正確,您可以將「from @billing」替換爲「from(從客戶名稱中選擇custname,billdate from billname,billdate)sub」 – Andomar 2009-10-16 13:48:12

0

怎麼樣:

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

這是有點我需要,但我還需要多個WHERE條件,我認爲CASE聲明將做,謝謝 – 2009-10-16 12:21:32

1

如果幾個月都在一個序列,我們都限制我們的搜索到某一年,然後(結算時間)最小(月)+計數 - 1應該= MAX(月)。

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

感謝這有助於 – 2009-10-16 12:20:31

1

這裏的建議基於一個假設,即在同一個月內您永遠不會向客戶收取兩次或更多費用。如果這不是一個安全的假設,你需要一個不同的方法。讓我們知道如果是這樣的話。

+1

好點,可以用羣組解決通過子查詢 – Andomar 2009-10-16 09:48:03

+0

您是對的,但我不需要知道他們是否在一個月內被收取超過一次的費用。我認爲GROUP BY會照顧到這種情況。查詢是否在給定的時間內進行一些業務分析分析。 – 2009-10-16 12:18:00

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 2009-10-16 09:47:02

+0

是的,那是事實。在我未說明的假設中,無論是視圖定義還是第二個最終SELECT都會將查詢限制爲小於數據庫中整個月份的範圍。 – 2009-10-16 11:18:53

+0

是的,我之前試過UNION ALL和SUB SELECTS,而且我得到了我需要的結果,但我認爲CASE聲明是最好的方法,最終我會喜歡。感謝您的輸入 – 2009-10-16 12:19:42