我应该使用分区还是有更好的方法?

时间:2012-09-17 07:26:25

标签: sql sql-server-2008 tsql

我有一个表结构,简化如下:

period_id int
suite_id varchar(20)
suite_status varchar(50)

每个月都会分配一个句点ID。每个套件都有一个每月的记录(period_id)。套房状态可以是“空置”或“主动租赁”。我正在尝试撰写一个查询,显示自2011年7月1日以来租赁的前五大交易,这些交易在成为有效租约之前空置的时间最长,但我不知道如何处理。

我最初的方法是将每个租约按其空置的期数排序,如下:

;WITH cte_vacancy_periods AS
(
        SELECT  lp.suite_id ,
                count(lp.period_id) AS 'Periods Vacant'
        FROM    property.lease_period lp
        WHERE   lp.suite_status = 'Vacant'
                        OR
                        (       isnull(lp.suite_status, '') = ''
                                AND     lp.lease_id = 'No Lease'        )
        GROUP BY
                lp.suite_id
        ORDER BY count(lp.period_id) desc
)

我当时计划将这一点与自258期(2011年7月1日至2011年)以来的有效租赁交叉引用。

不幸的是,如果租约空置两个月,然后租赁一个月,然后再空置两个月(在租赁之前总共有四个月空置,当它应该是两个月)时,这不起作用。

我确信这可以通过分区来完成,但是我试图做到这一点并且不太了解它们。我对于解决这个问题的知识缺少什么?如果我对数据的解释很差,那么我很难理解我想要做什么,请告诉我,我会详细说明我能做什么。

1 个答案:

答案 0 :(得分:1)

希望像这样的方法会有所帮助。

我必须承认,我并不是100%清楚你正在寻找的最终结果,但这应该会为你提供一个数据集,可以回答与你类似的许多问题。

WITH
  reformatted_data
AS
(
  SELECT
    suite_id,
    period_id,
    CASE
      WHEN suite_status = 'Vacant'                                 THEN 0
      WHEN lease_id = 'No Lease' AND isnull(suite_status, '') = '' THEN 0
                                                                   ELSE 1
    END as suite_status
  FROM
    properties.lease_period
)
,
  gaps_and_islands
AS
(
  SELECT
    suite_id,
    period_id,
    suit_status,
    ROW_NUMBER() OVER (PARTITION BY suite_id               ORDER BY period_id) AS seq,
    ROW_NUMBER() OVER (PARTITION BY suite_id, suite_status ORDER BY period_id) AS seq_status
  FROM
    reformatted_data
)

SELECT
  suite_id,
  suit_status,
  MIN(period_id)       AS first_period_id,
  MAX(period_id)       AS last_period_id,
  MAX(seq) - MIN(seq)  AS consecutive_periods
FROM
  gaps_and_islands
GROUP BY
  suite_id,
  suite_status,
  seq - seq_status