SQL如何从多个查询中进行一个查询

时间:2009-10-15 20:30:01

标签: sql

我有一张表,其中包含结算记录的月度数据。所以说Customer 1234在1月/ 2月收费,Customer 2345收费是1月/ 2月/ 3月。如何对这些进行分组以向我显示并发的每月结算周期。但也需要有非并发计费月,所以Customer 3456收费2月/ Apl / 6月/ 8月

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

有什么建议吗?

5 个答案:

答案 0 :(得分:1)

如果这些月份都在一个序列中,并且我们将搜索限制在特定年份,那么Min(月)+ Count(计费时间) - 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

答案 1 :(得分: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(*) 

但在那种情况下,我想知道你如何区分岁月。

答案 2 :(得分:1)

此处的建议基于这样的假设,即您绝不会在同一个月向客户收取两次或更多的费用。如果这不是一个安全的假设,那么您需要一种不同的方法。如果是这种情况,请告诉我们。

答案 3 :(得分:0)

怎么样:

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

答案 4 :(得分: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类型函数,取决于你正在使用的确切数据库)。

相关问题