我有一个处理学校假期的申请。不幸的是,有三种不同的学校假期:全国范围,联邦州和城市假期。我将所有信息存储在表days
,表vacation_periods
和连接表slots
中:
days {
id:integer
date_value:date
}
slots {
id:integer
day_id:integer
vacation_period_id:integer
}
vacation_periods {
id:integer
starts_on:date
ends_on:date
name:string
country_id:integer
federal_state_id:integer
city_id:integer
}
我想在特定时间范围内选择所有days
。让我们说2017年1月1日到2017年1月31日。我可以通过以下方式获取days
:
SELECT * FROM days WHERE date_value >= '2017-01-01' AND
date_value <= '2017-01-31';
但对于我的假期日历,我不仅需要days
,还需要vacation_periods
所在的信息。假设我搜索那个时间范围内有
vacation_periods
country_id == 1 or federal_state_id == 5 or city_id == 30
我读过有关JOINS和LEFT JOINS的内容,这似乎是问题的解决方案。但我不能把所有东西都放在一起。
是否可以发送一个SQL请求,该请求在请求的时间范围内返回所有days
,如果符合vacation_period
规则的country_id == 1 or federal_state_id == 5 or city_id == 30
通过{{1}连接,则可以发送其他信息每个slots
。包括day
的名称?
如果一个请求不可能:哪个是在数据库中解决此问题的最快方法?请求多少?什么样的要求?
如果可能的话,我希望得到某种形式的结果:
vacation_period
答案 0 :(得分:1)
以下查询可能会为您提供所需的答案:
SELECT * FROM days WHERE date_value >= '2017-01-01' AND date_value <='2017-01-31'
INNER JOIN slots ON days.id = slots.day_id
INNER JOIN vacation_periods ON vacation_periods.id = slots.vacation_period_id
答案 1 :(得分:0)
我认为您可以使用
获得所需内容的未格式化版本(可以将其处理为分层输出)CREATE TYPE vacation_authority AS ENUM
('COUNTY', 'FED-STATE', 'CITY');
/* not necessary, but cleans up the vacation_period table */
更改为允许vacation_period
只有一个ID,以及authority
类型的新字段vacation_authority
。您现在可以使用id字段或(id,权限)创建主键,具体取决于休假数据进入系统的方式。
SELECT date_value, vp.name, vp.id /* is the ID meaningful or arbitrary? */
FROM dates LEFT JOIN vacation_periods vp
WHERE date_value BETWEEN vp.starts_on AND vp.ends_on; -- inclusive range
现在,如果跨越给定日期有多个假期,那么这将是输出中的多个记录。在这种情况下,你不清楚你想要什么。
答案 2 :(得分:0)
其他答案都没有能够解决我的问题,但他们让我解决了这个问题,所以我很感激他们。这是解决方案:
SELECT days.date_value, slots.period_id, vacation_periods.name FROM days
LEFT OUTER JOIN slots ON (days.id = slots.day_id)
LEFT OUTER JOIN vacation_periods ON (slots.period_id = vacation_periods.id)
WHERE days.date_value >= '2017-01-05'
AND days.date_value <='2017-01-15'
AND (vacation_periods.id IS NULL
OR vacation_periods.country_id = 1
OR vacation_periods.federal_state_id = 5)
ORDER BY days.date_value;