强制内部查询在外部查询之前执行

时间:2011-04-14 09:36:25

标签: sql sql-server tsql join

我有两张桌子需要加入:

表VarValues的字段值是一个varchar,包含属性类型可以是text og int的自定义属性

Table Vars具有属性类型。

表项目中包含项目,特别是全文索引的id和数据,我需要搜索。

当我这样查询时:

SELECT 
    distinct SelectedItems.itemid,SelectedItems.fileid
FROM 
    (
        SELECT  [values].itemid, convert(int, [value]) as fileid
        FROM 
            VarValues [values]
            JOIN Vars vars ON [values].VarID = vars. ID
        WHERE
            [type] = 6 --This type is an int
            AND
            [values].[value] <> ''
    ) as SelectedItems
    JOIN containstable(items, *, '<some query>') as items ON SelectedItems.fileid = items.[KEY]

内部查询只返回整数作为fileid,但是当整个查询运行时,我得到一个错误,因为VarValues中的第一行包含文本,尽管类型不是6。

查询优化器是否在弄乱我的内部查询?我怎么能让它停下来?或者我完全错了吗?

3 个答案:

答案 0 :(得分:2)

优化器可以扩展视图(包括内联视图)并可以自由决定过滤顺序。

换句话说,它可能首先使用全文表执行连接,然后在type = 6上过滤结果(在您的情况下似乎正在执行此操作)。

您可以尝试将OPTION (FORCE ORDER)添加到查询中,但是,它只保证连接操作中表的顺序,而不是过滤器应用的顺序。

尝试重写您的查询:

SELECT 
    distinct SelectedItems.itemid,SelectedItems.fileid
FROM 
    (
        SELECT  [values].itemid, CAST(CASE WHEN IsNumeric([value]) = 1 THEN [value] END AS INT) AS field
        FROM 
            VarValues [values]
            JOIN Vars vars ON [values].VarID = vars. ID
        WHERE
            [type] = 6 --This type is an int
            AND
            [values].[value] <> ''
    ) as SelectedItems
    JOIN containstable(items, *, '<some query>') as items ON SelectedItems.fileid = items.[KEY]

答案 1 :(得分:1)

您可以尝试将内部查询的结果保存在临时/变量表中,并在主查询中使用它。

类似的东西:

CREATE TABLE #vars (itemid, fileid)

-- store values for inner query
INSERT INTO 
    #vars (itemid, fileid)
SELECT  
    [values].itemid, 
    CAST(CASE WHEN IsNumeric([value] = 1 THEN [value] END AS INT) AS field
FROM 
    VarValues [values]
    JOIN 
        Vars vars 
    ON 
        [values].VarID = vars.ID
WHERE
    [type] = 6 --This type is an int
    AND [values].[value] <> ''


SELECT 
    distinct SelectedItems.itemid,SelectedItems.fileid
FROM 
    #vars as SelectedItems
    JOIN containstable(items, *, '<some query>') as items ON SelectedItems.fileid = items.[KEY]    

这可以解决您的问题。

答案 2 :(得分:0)

我认为您还可以将条件IsNumeric([value]) = 1添加到第一个联接:

SELECT 
    distinct SelectedItems.itemid,SelectedItems.fileid
FROM 
    (
        SELECT  [values].itemid, convert(int, [value]) as fileid
        FROM 
            VarValues [values]
            JOIN Vars vars ON [values].VarID = vars. ID
                          AND IsNumeric([value]) = 1 
        WHERE
            [type] = 6 --This type is an int
            AND [values].[value] <> ''
    ) as SelectedItems
    JOIN containstable(items, *, '<some query>') as items
      ON SelectedItems.fileid = items.[KEY]