SQL按月、按用户、按地点计算居住天数
我正在对一个康复组织进行查询,其中租户(客户/患者)第一次到达时住在一栋大楼里,随着治疗的进展,他们搬到另一栋大楼,当他们接近治疗结束时,他们住在一栋大楼里。第三栋大楼。
出于资金目的,我们需要知道租户每个月在每栋建筑中度过了多少个夜晚。 我可以使用 DateDiff 获取总晚数,但如何获取每栋大楼每个月每个客户的总晚数?
例如,John Smith 在 A 楼 9/12-11/3;搬至 B 楼 11/3-15;搬到 C 楼并仍然在那里:11/15 - 今天
哪个查询返回的结果显示他在以下地方度过的夜晚数: A 楼于 9 月、10 月和 11 月。 11月B座 11 月 C 栋
两张桌子上有客户姓名、大楼名称以及入住日期和退房日期,
CREATE TABLE [dbo].[clients](
[ID] [nvarchar](50) NULL,
[First_Name] [nvarchar](100) NULL,
[Last_Name] [nvarchar](100) NULL
) ON [PRIMARY]
--populate w/ two records
insert into clients (ID,First_name, Last_name)
values ('A2938', 'John', 'Smith')
insert into clients (ID,First_name, Last_name)
values ('A1398', 'Mary', 'Jones')
CREATE TABLE [dbo].[Buildings](
[ID_U] [nvarchar](50) NULL,
[Move_in_Date_Building_A] [datetime] NULL,
[Move_out_Date_Building_A] [datetime] NULL,
[Move_in_Date_Building_B] [datetime] NULL,
[Move_out_Date_Building_B] [datetime] NULL,
[Move_in_Date_Building_C] [datetime] NULL,
[Move_out_Date_Building_C] [datetime] NULL,
[Building_A] [nvarchar](50) NULL,
[Building_B] [nvarchar](50) NULL,
[Building_C] [nvarchar](50) NULL
) ON [PRIMARY]
-- Populate the tables with two records
insert into buildings (ID_U,Move_in_Date_Building_A,Move_out_Date_Building_A, Move_in_Date_Building_B,
Move_out_Date_Building_B, Move_in_Date_Building_C, Building_A, Building_B, Building_C)
VALUES ('A2938','2010-9-12', '2010-11-3','2010-11-3','2010-11-15', '2010-11-15', 'Kalgan', 'Rufus','Waylon')
insert into buildings (ID_U,Move_in_Date_Building_A,Building_A)
VALUES ('A1398','2010-10-6', 'Kalgan')
谢谢您的帮助。
I'm working on a query for a rehab organization where tenants (client/patients) live in a building when they first arrive, as they progress in their treatment they move to another building and as they near the end of treatment they are in a third building.
For funding purposes we need to know how many nights a tenant spent in each building in each month.
I can use DateDiff to get the total number of nights, but how do I get the total for each client in each month in each building?
For example, John Smith is in Building A 9/12-11/3; moves to Building B 11/3-15; moves to Building C on and is still there: 11/15 - today
What query returns a result that show the number of nights he spent in:
Building A in Septmeber, October and November.
Buidling B in November
Building C in November
Two tables hold the client's name, building name and move-in date and move-out date
CREATE TABLE [dbo].[clients](
[ID] [nvarchar](50) NULL,
[First_Name] [nvarchar](100) NULL,
[Last_Name] [nvarchar](100) NULL
) ON [PRIMARY]
--populate w/ two records
insert into clients (ID,First_name, Last_name)
values ('A2938', 'John', 'Smith')
insert into clients (ID,First_name, Last_name)
values ('A1398', 'Mary', 'Jones')
CREATE TABLE [dbo].[Buildings](
[ID_U] [nvarchar](50) NULL,
[Move_in_Date_Building_A] [datetime] NULL,
[Move_out_Date_Building_A] [datetime] NULL,
[Move_in_Date_Building_B] [datetime] NULL,
[Move_out_Date_Building_B] [datetime] NULL,
[Move_in_Date_Building_C] [datetime] NULL,
[Move_out_Date_Building_C] [datetime] NULL,
[Building_A] [nvarchar](50) NULL,
[Building_B] [nvarchar](50) NULL,
[Building_C] [nvarchar](50) NULL
) ON [PRIMARY]
-- Populate the tables with two records
insert into buildings (ID_U,Move_in_Date_Building_A,Move_out_Date_Building_A, Move_in_Date_Building_B,
Move_out_Date_Building_B, Move_in_Date_Building_C, Building_A, Building_B, Building_C)
VALUES ('A2938','2010-9-12', '2010-11-3','2010-11-3','2010-11-15', '2010-11-15', 'Kalgan', 'Rufus','Waylon')
insert into buildings (ID_U,Move_in_Date_Building_A,Building_A)
VALUES ('A1398','2010-10-6', 'Kalgan')
Thanks for your help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我会使用正确规范化的数据库模式,您的建筑物表没有这样的用处。拆分之后我相信得到你的答案会很容易。
编辑(和更新):这是一个 CTE,它将采用这个奇怪的表结构并将其拆分为更规范化的形式,显示用户 ID、建筑物名称、迁入和迁出日期。通过对您想要的数据进行分组(并使用
DATEPART()
等),您应该能够获得您需要的数据。对示例数据运行的此查询会产生以下输出:
如您所见,从这里开始,可以更轻松地隔离每个患者或建筑物的天数,还可以查找特定月份的记录并计算正确的停留时间那种情况。请注意,CTE 显示仍在建筑物中的患者的当前日期。
编辑(再次):为了获取所有月份,包括所有相关年份的开始和结束日期,您可以使用如下的 CTE:
因此,由于我们现在有可能感兴趣的所有日期范围的表格表示,我们只需将其连接在一起:
最终产生以下输出:
I'd use a properly normalized database schema, your Buildings table is not useful like this. After splitting it up I believe that getting your answer will be pretty easy.
Edit (and updated): Here's a CTE which will take this strange table structure and split it into a more normalized form, displaying the user id, building name, move in and move out dates. By grouping on the ones you want (and using
DATEPART()
etc.) you should be able to get the data you need with that.This query run on your sample data produces he following output:
As you can see, from here on it will be much easier to isolate the days per patient or building, and also to find the records for specific months and calculate the correct stay duration in that case. Note that the CTE displays the current date for patients which are still in a building.
Edit (again): In order to get all months including their start and end dates for all relevant years, you can use a CTE like this:
So since we now have a tabular representation of all date ranges which can be of interest, we simply join this together:
Which finally produces this output:
-- 设置您想要的月份的日期
-- set the dates for which month you want
尝试使用日期表。例如,您可以像这样创建一个:
只需修改初始日期数量即可满足您的需求(在我的测试实例上,上面生成的日期是从 2000-01-02 到 2015-10-26)。对于日期表,查询非常简单,如下所示:
Try using a date table. For example, you could create one like so:
Just modify the initial Dates population to meet your needs (on my test instance, the above yielded dates from 2000-01-02 to 2015-10-26). With a dates table, the query is pretty straight forward, something like this:
如果您无法重组 Building 表,您可以创建一个查询来对其进行规范化并允许更轻松的计算:
If you can't restructure the Building table you can create a query that will normalize it for you and allow for easier calculations: