在项目的种种需求中,我们偶尔会遇到以下场景:
有如下一张表,记录了起点站、终点站、发车时间:

现需要将此表格中的数据查询出来,以如下形式在页面中展现,以起点站和终点站分组,显示当天发车的时间表:

按傻瓜式的做法,我们通常会将表中的数据原样查询出来,然后在.net代码中遍历查询结果,另外构建一个DataTable或者集合进行数据变形。这种做法在编码时的确省心省力,但若查询数据量较大,代码的执行效率就不高了。
这里推荐使用FOR XML PATH的语句进行查询,贴上代码:
SELECT
StartStation,
TerminalStation,
StartTimeList= STUFF((
SELECT '、'+DATENAME(HOUR, tblJoin.StartTime) + ':' + DATENAME(MINUTE, tblJoin.StartTime)
FROM tblTest tblJoin
WHERE
tblJoin.StartStation=tblMain.StartStation
AND tblJoin.TerminalStation=tblMain.TerminalStation
FOR XML PATH('')
),1,1,'')
FROM tblTest tblMain
WHERE tblMain.StartTime>='2015-12-17 00:00:00' AND tblMain.StartTime<'2015-12-18 00:00:00'
GROUP BY StartStation, TerminalStation用FOR XML PATH拼接时间字段,并用STUFF截取拼接的第一个顿号(、),运行后成功获取到想要的数据形式。
当然,对于不了解SQL,又不想在.net中使用那么冗长的数据变形代码的同学们来说,LINQ就是你的福音了,以下贴上LINQ代码截图,也可以达到相同的页面展示效果,只是代码执行效率没有直接用SQL的效率高,代码还是相当简洁的:
var busSchedules = GetBusScheduleList();
var data = from s in busSchedules
group s by new
{
s.StartStation,
s.TerminalStation
}
into g
let startTimeList = g.Select(p => p.StartTime.ToString("mm:ss")).ToArray()
select new
{
StartStation = g.Key.StartStation,
TerminalStation = g.Key.TerminalStation,
StartTimeList = string.Join("、", startTimeList)
};需要查看SQL和LINQ代码的同学请下载附件: