1

I would appreciate a little advice on the most appropriate method for managing bookings.

I am adding to an existing program, written in VB with an MSSql DB.

I am currently using win forms as the GUI, utilising a DataGridView to display the data with a Month control.

My current DB schema is:

bikeDetail (bikeID (PK), bikeName, bikeColour, bikeStyle, bikeNotes)

bikeMovements (bikeMovementID (PK), bikeID, customerID, bikeMovementType, bikeMovementDate, bikeMovementAMPM, bikeMovementNotes).

customer (customerID, ..., ...)

The idea is that each time a bike is taken in or out, a record is made in the bikeMovements database. This may not be the easiest way of saving this data, but it should hopefully mean the database won't get bloated with lots of repeated data.

My problem is that I am struggling to work out the best way to search through the bikeMovements table in order to find out if bikes are in or out, and are hence available to book out. Using the calendar tool I am able to select a range of dates.

So far, I have been able to work out if a bike is available on a certain date by using a sql query, but not for the range of dates.

Current sql query:

    SELECT * FROM tb_bikeMovements as bm, tb_bikeDetail as bd
    WHERE bm.bikeMovementDate < '" + startDate + "'
    and bm.bikeID = bd.bikeID
    and bm.bikeMovementType = 1 

This returns the bikes that are available from that day onward. (bikeMovementType 1 is the bike coming back in, and hence is available).

I would appreciate any advice on either a better sql query for bringing back availability, or a better way to setup the DB that would make querying it simpler.

Example dates:

bike 1 goes out on 22 April, and is booked back in for 24 April (available from 25 April)
bike 2 goes out on 22 April, and is booked back in for 28 April (available from 29 April)
bike 3 goes out on 26 April, and is booked back in for 27 April (available from 28 April)
bike 4 is available from 22 April onward.

What bikes are available for 25 - 29 April? (should be bike 1 and 4. Catching bike 1 is easy, bike 3 is the fly in the ointment as it goes out and back in within the selected date range!).

I am thinking that the easiest way would be to change my DB schema so that a record is created for every day that a bike is booked out for. This will make it a lot easier to search for availability, but will make the table way more bloated (2 records for each bike hire currently, in and out), with a record for every day the bike is out. To be fair though, we are not yet sure how many days these bikes will be rented for, and this would have an impact on my decision.

Any advice will be gratefully received!

4

1 回答 1

1

如果我理解正确,那么如果在要求的日期范围内有运动记录(出或入),则自行车不可用(归还后的第二天可用),如果最后的运动记录已出,则自行车也不可用

查询

select distinct bikeid from bikemovements where bikeMovementDate between '25 April 2013' and '29 April 2013'

会给在 4 月 25 日至 29 日之间进出的自行车

所以我们可以通过使用“不在”来查找可用的自行车来否定这一点

select * from bikeDetail where bikeid not in (
  select distinct bikeid from bikemovements where bikeMovementDate between '25 April 2013' and '29 April 2013'
) 

但我想我们也应该检查一下自行车是否已经预订完毕并且还没有进来

这将获得每辆自行车的最后运动日(直到开始日期)

  select bikeid bid, max(bikemovementdate) bmd from bikemovements
  where bikemovementdate < '25 April 2013' 
  group by bikeid) lastmove 

并查找运动记录,我们可以

select * from bikemovements join 
(
  select bikeid, max(bikemovementdate) bmd from bikemovements
  where bikemovementdate < '25 April 2013' 
  group by bikeid
) lastmove 
on lastmove.bikeid=bikemovements.bikeid and 
   lastmove.bmd=bikemovements.bikemovementdate

只找到最后移动为 out 的那些

select bikemovements.bikeid from bikemovements join 
(
  select bikeid, max(bikemovementdate) bmd from bikemovements
  where bikemovementdate < '25 April 2013' 
  group by bikeid) lastmove 
on lastmove.bikeid=bikemovements.bikeid and 
   lastmove.bmd=bikemovements.bikemovementdate
where bikeMovementType = 'out'

所以把它们放在一起,我们可以有一些类似的东西

select * from bikeDetail where bikeid not in (
select distinct bikeid from bikemovements 
  where bikeMovementDate between '25 April 2013' and '28 April 2013'
  ) 
and bikeid not in ( 

select bikemovements.bikeid from bikemovements join 
(
  select bikeid, max(bikemovementdate) bmd from bikemovements 
  where bikemovementdate < '25 April 2013' 
  group by bikeid
) lastmove 
 on lastmove.bikeid=bikemovements.bikeid and 
   lastmove.bmd=bikemovements.bikemovementdate
 where bikeMovementType = 'out'
)

sql小提琴

于 2013-04-23T09:25:16.913 回答