SQL Server查询:将行转换为列

时间:2016-02-04 08:00:37

标签: sql-server sql-server-2008

我有一个包含VisitorNamevitising_datelocation Id列的表格。我需要与上个月访客一起显示当前月访客位置的记录

SQL FIDDLE

表架构:

CREATE TABLE visitors
(
    [id] [bigint] IDENTITY(1,1) NOT NULL,
    [name] varchar(50),
    [location_id] [bigint],
    [visited_date] [datetime]
);

name   location_id    visited_date
David      1           2016-01-04
John       1           2016-01-02
Andrea     1           2016-01-05
Ely        2           2016-01-04
Andrea     1           2016-02-02
John       1           2016-02-02
Peter      2           2016-02-02

查询当前月份记录:

select * 
from visitors 
where 
    DATEPART(month, visited_date) = DATEPART(MONTH, GETDATE()) 
    and DATEPART(year, visited_date) = DATEPART(year, getdate())

但我需要数据显示上个月的记录,就像这个

  Locationid   Name     Date        LastMonthVisitor   LastMonthVisitingDate
   1           Andrea   2016-02-02  Andrea              2016-01-05 
   1             John   2016-02-02  David               2016-01-04 
   1            'NA'    'NA'        John                2016-01-02 

   2            Peter  2016-02-02   Ely                 2016-01-04 
  1. 记录按地点ID显示当前月份组的访客列表(位置ID为外键)
  2. 现在我需要按位置ID
  3. 列出上个月的访客群组

    这些结果按日期排列在彼此旁边。 他们可能会改变上个月访问者记录为5的location_id 1和当前月访问者为2 所以最后它会显示5条记录。它们与当前月份访问者名称,LastMonth访问者名称无关。

    我可以通过位置ID在服务器端C#和显示LastMonthVisitor组的显示CurrentMonthVisitors列表。但我正在尝试SQL。

1 个答案:

答案 0 :(得分:1)

试试这个,它没有给出完全相同的结果,但在我看来,你的预期结果与数据不匹配:

;WITH CTE as
(
  SELECT
   *, 
   -- setting a row number based on month, and location
   row_number() over 
     (partition by datediff(month, 0, visited_date), 
     location_id order by visited_date, name) rn,
    datediff(month, 0, visited_date) month
  FROM visitors
  WHERE
    -- current and last month
    visited_date >= dateadd(month, datediff(month, 0, getdate()) - 1, 0) and
    visited_date < dateadd(month, datediff(month, -1, getdate()), 0)
)
SELECT 
  CTE.location_id Locationid,
  COALESCE(CTE.Name, 'N/A') Name,
  CAST(CTE.visited_date as Date) Date,
  COALESCE(CTE2.name, 'N/A') LastMonthVisitor,
  CAST(CTE2.visited_date as Date) LastMonthVisitingDate
FROM CTE
-- full join to get data when there is not matching data for the other month
FULL JOIN
CTE CTE2
ON CTE.rn = CTE2.rn
and CTE.location_id = CTE2.location_id
and CTE.month = CTE2.month-1
WHERE
  -- making sure CTE is last month or CTE2 is current month
  cte.month =datediff(month, 0, getdate()) - 1 or
  cte2.month=datediff(month, 0, getdate())