我正在尝试将一些C#移植到TSQL,因为性能不令人满意。 C#进行多次数据库调用。
这是适用于住宿物业的刮刀。架构如下:
擦伤
ScrapeResults
基本上,这一点的重点是数据库跟踪内部房价与竞争对手相比较。 fkRoomId
上的ScrapeResults
列唯一地定义了每个房间。每次刮擦竞争对手时,Scrapes表中都会有一个新条目,并且Scrape的结果会保存在ScrapeResults中。开始和结束日期为1周。每周的价格为3个月。刮伤每周发生一次,这是fkSessionId
与独特刮擦会话相关的目的。
C#代码构建一个如下所示的报告:
我不太确定是否可以为此构建SQL查询。我编写了一个存储过程来构建动态SQL字符串。这是我的第一次尝试:
select sr.ScrapeId,
sr.fkProviderId,
sr.startDate,
sr.endDate,
sr1.price,
sr2.price,
sr3.price,
sr4.price,
sr5.price,
sr6.price,
sr7.price,
sr8.price,
sr9.price,
sr10.price,
sr11.price,
sr12.price
from Scrapes sr
left join ScrapeResults sr1 on sr1.fkScrapeId = sr.ScrapeId
left join ScrapeResults sr2 on sr2.fkScrapeId = sr.ScrapeId
left join ScrapeResults sr3 on sr3.fkScrapeId = sr.ScrapeId
left join ScrapeResults sr4 on sr4.fkScrapeId = sr.ScrapeId
left join ScrapeResults sr5 on sr5.fkScrapeId = sr.ScrapeId
left join ScrapeResults sr6 on sr6.fkScrapeId = sr.ScrapeId
left join ScrapeResults sr7 on sr7.fkScrapeId = sr.ScrapeId
left join ScrapeResults sr8 on sr8.fkScrapeId = sr.ScrapeId
left join ScrapeResults sr9 on sr9.fkScrapeId = sr.ScrapeId
left join ScrapeResults sr10 on sr10.fkScrapeId = sr.ScrapeId
left join ScrapeResults sr11 on sr11.fkScrapeId = sr.ScrapeId
left join ScrapeResults sr12 on sr12.fkScrapeId = sr.ScrapeId
WHERE sr.fkSession = 25
and sr.startDate='2014-03-22'
and sr.fkLocationId = 1
and sr1.fkRoomId = 11
and sr2.fkRoomId = 15
and sr3.fkRoomId = 19
and sr4.fkRoomId = 23
and sr5.fkRoomId = 25
and sr6.fkRoomId = 27
and sr7.fkRoomId = 32
and sr8.fkRoomId = 39
and sr9.fkRoomId = 41
and sr10.fkRoomId = 45
and sr11.fkRoomId = 47
and sr12.fkRoomId = 50
我知道我不在这里,但会很感激指针。感谢。
答案 0 :(得分:1)
您正在通过srX.fkRoomId =
打破左连接
所以不妨只做一个加入
或者以这种格式,你实际上可以做一个左连接而不是打破它
查询优化器通常可以使用语法
做得更好
我认为在C#
select sr.ScrapeId,
sr.fkProviderId,
sr.startDate,
sr.endDate,
sr1.price,
sr2.price,
...
from Scrapes sr
join ScrapeResults sr1
on sr1.fkScrapeId = sr.ScrapeId
and sr1.fkRoomId = 11
join ScrapeResults sr2
on sr2.fkScrapeId = sr.ScrapeId
and sr2.fkRoomId = 15
....
WHERE sr.fkSession = 25
and sr.startDate='2014-03-22'
and sr.fkLocationId = 1
答案 1 :(得分:1)
使用PIVOT选项,在fkRoomID列上进行旋转,可以更简单地完成此操作。您可以使用单个查询手动执行此操作,但这会让我感到烦恼,因为您必须在SQL中为PIVOT语句指定fkRoomID值,因此如果更改了房间数,则必须更改SQL,如下所示:
select
sc.ScrapeId,
sc.fkProviderId,
sc.startDate,
sc.endDate,
scr.fkRoomId,
scr.price
from
Scrapes sc
join ScrapeResults scr
on ( scr.fkScrapeId = sr.ScrapeId )
pivot (max(price) for fkRoomId in ([11],[15],[19],[23],[25],[27],[32],[39],[41],[45],[47],[50]))
where
sr.fkSession = 25
and sr.startDate = '2014-03-22'
and sr.fkLocationId = 1
我更喜欢使用我写的名为pivot_query的存储过程。要使用它,您可以格式化您的查询:
declare @mySQL varchar(MAX);
set @mySQL = '
select
sc.ScrapeId,
sc.fkProviderId,
sc.startDate,
sc.endDate,
scr.fkRoomId,
scr.price
from
Scrapes sc
join ScrapeResults scr
on ( scr.fkScrapeId = sr.ScrapeId )
where
sr.fkSession = 25
and sr.startDate = ''2014-03-22''
and sr.fkLocationId = 1
';
exec pivot_query @mySQL, 'StartDate, EndDate, fkProviderId','fkRoomId','max(price)'
这是基本概念,但如果您有另一个带有房间名称的参考表,您也可以加入该表并使用房间名称进行转动,因此列的房间名称将位于顶部
有一些使用pivot_query proc here的例子。