MSSQL / TSQL加入子查询

时间:2017-03-30 03:41:19

标签: sql-server iis sharepoint

我正在分析来自sharepoint的IIS日志文件,需要将每个条目与其SPWeb匹配。

此SQL代码适用于单个值(@ var1):

DECLARE @var1 varchar(128);         
set @var1 = '/sites/Site1/Subsite1/Subsite2/Documents/marketing.docx';

select
    TOP 1 *,
    charindex(urlstub, @var1) as found 
from 
    spwebs
where
    charindex(urlstub, @var1)  = 1
order by
    urlstub DESC;

我正在寻找一种方法来使这个表适用于数据表而不仅仅是单个变量@ var1。

示例数据

SPwebs:    
/sites/Site1
/sites/Site1/Subsite1
/sites/Site1/Subsite1/Subsite2
/sites/Site2
etc..

IISlog: (this is the table I'd like to take the place of @var1 above) 
/sites/Site1/Subsite1/Subsite2/Documents/marketing.docx
/sites/Site1/Subsite1/Subsite2/Documents/sales.docx
/sites/Site1/Subsite1/Subsite2/Documents/hr.docx
/sites/Site1/research/funding.docx

上述预期结果将是: Foreach表中的IISLog记录: 从spwebs表中找到最佳/最深的匹配记录:

|table                                                    | matchingSPweb                   |
|---------------------------------------------------------| --------------------------------|
| /sites/Site1/Subsite1/Subsite2/Documents/marketing.docx | /sites/Site1/Subsite1/Subsite2/ |
| /sites/Site1/Subsite1/Subsite2/Documents/sales.docx     | /sites/Site1/Subsite1/Subsite2/  |
| /sites/Site1/Subsite1/Subsite2/Documents/hr.docx        | /sites/Site1/Subsite1/Subsite2/  |
| /sites/Site1/research/funding.docx                      | /sites/Site1                     | 

我试过

select iislogs2.*, spwebs.urlstub
from 
iislogs2
inner join 
(   
  select TOP 1 urlstub, csURIStem as found 
  from spwebs
   where charindex(urlstub, iislogs2.csUriStem)  = 1
  order by urlstub DESC
)   as x
on x.csuristem = iislogs2.csUriStem

但这只是错误,它似乎不理解subselect语句的上下文中的csUriStem。

1 个答案:

答案 0 :(得分:1)

解决问题的最简单方法是更改​​当前查询以在select语句中使用子查询,例如:

SELECT iislogs2.*, x.urlstub
from iislogs2
cross apply (SELECT TOP 1 urlstub FROM spwebs WHERE CHARINDEX(urlstub, iislogs2.csUriStem) = 1 ORDER BY urlstub DESC) AS x;

...或将您当前的联接更改为交叉申请,例如:

;WITH CTE AS
(
    SELECT i.csUriStem, s.urlstub, RN = ROW_NUMBER() OVER (PARTITION BY i.csUriStem ORDER BY s.urlstub DESC)
    FROM iislogs2 AS i
    JOIN spwebs AS s
        ON i.csUriStem LIKE s.urlstub + '%'
)
SELECT i.*, c.urlstub
FROM iislogs2 AS i
LEFT JOIN CTE AS c
    ON c.csUriStem = i.csUriStem
    AND c.RN = 1;

修改: 查询优化器可能会执行各种奇怪的排序和假脱机,因此避免这种情况的一个选项可能是使用CTE的显式连接,然后将其连接回原始表。例如:

self.txtName.delegate = self;

不幸的是,对于字符串和子字符串,很难获得真正最适合您想要做的事情的执行计划,但我希望这种查询在索引方面的表现要比其他方法更好2。