如何减去不同表

时间:2016-02-07 14:06:45

标签: sql

我有一张病房表

ward_number | class | capacity
________________________________________
1           | A1    | 1
2           | A1    | 2
3           | B1    | 3
4           | C     | 4
5           | B2    | 5

容量=病房里有多少张病床

我还有一张名为ward_stay的表:

ward_number | from_date   | to_date
_____________________________________________
2           | 2015-01-01  | 2015-03-08
3           | 2015-01-16  | 2015-02-18
6           | 2015-03-05  | 2015-03-18
3           | 2015-04-15  | 2015-04-20
1           | 2015-05-19  | 2015-05-30

我想计算一下病房的床位数量' B1'日期' 2015-04-15':

ward_number  | count 
_____________________
  3          | 2     

如何获得计数基本上是容量 - ward_number 3出现的次数

我设法得到了ward_number 3出现的次数,但我不知道如何从此结果中减去容量。

这是我的代码:

select count(ward_number) AS 'result'
from ward_stay
where ward_number = (select ward_number
                     from ward 
                     where class = 'B1');

如何从此结果中减去容量?

3 个答案:

答案 0 :(得分:1)

<强> SQL Fiddle Demo

使用2015-01-17代替我计算当天occupied床的总数。然后加入以从原始capacity中减去。如果所有床位均免费,LEFT JOIN将返回NULL,因此COALESCE0

SELECT w."ward_number", "capacity" - COALESCE(occupied, 0) as "count"
FROM wards w
LEFT JOIN (
      SELECT "ward_number", COUNT(*) occupied
      FROM ward_stay
      WHERE to_date('2015-01-17', 'yyyy-mm-dd') BETWEEN "from_date" and "to_date"
      GROUP BY "ward_number"
     ) o     
  ON w."ward_number" = o."ward_number"
WHERE w."class" = 'B1'

<强>输出

| ward_number | count |
|-------------|-------|
|           3 |     2 |

答案 1 :(得分:0)

select w.ward_number,
   w.capacity - count(ws.ward_number) AS "result" 
from ward as w left join ward_stay as ws 
on ws.ward_number = w.ward_number
and date '2015-05-19' between ws.from_date and ws.to_date
where w.class = 'B1' -- which class
     -- bed not occupied on that date
group by w.ward_number, w.capacity
having w.capacity - count(*) > 0 -- only available wards

请参阅fiddle

答案 2 :(得分:0)

在返回之前,您需要聚合两个表,因为两者中的同一个单词类型都有多行。所以:

select c.class, (c.capacity - coalesce(wc.occupied)) as available
from (select class, sum(capacity) as capacity
      from ward
      group by class
     ) c left join
     (select w.class, count(*) as occupied
      from ward_stay ws join
           ward s
      on ws.ward_number = w.ward_number and
         '2015-05-19' between ws.from_date and ws.to_date
     ) wc
     on w.class = wc.class;

注意:除日期常量外,这是标准SQL。这适用于大多数数据库;有些可能有其他格式(或者可能取决于国际化设置)。

严格地说,“{1}}上的聚合对于”B1“不是必需的。但是“A1”显然是必要的。