T-SQL如果使用查找表替换其他(Case When)

时间:2015-11-11 10:00:11

标签: sql if-statement sql-server-2012 lookup case-when

*修改

正如我所指出,我的问题提供了必要的细节。所以我会尽量准确。

在水晶报告中使用膨胀的If Else结构。结果是csv导出。这是它现在的工作方式。 :)设计决定是重做这个并生成动态SQL。因此,这些膨胀的If Else结构将成为SQL查询的一部分。

现在我已经实现了一个modell来动态创建T-SQL。我想出了一个表,其中包含查询的Select部分的列定义,一个包含连接条件的表和一个包含where条件的表。在存储过程中,收集所有信息并且结果是T-SQ1查询。

SELECT Column Definition Table:

ColumnName  T-SQL                           OrderID IncludeInSelectList InterfaceID_ID
Monat       SUBSTRING(CP.TCOEP_PERIO, 2,2)  1       1                   1
Jahr        CP.TCOEP_GJAHR                  2       1                   1

问题是在具有列定义的表中,将存储SQL定义的列(例如,Substring(ColA,2,3))具有4000个字符的最大长度限制。

我试图解释的越多,我就越觉得试图把所有东西都放到一个巨大的查询中根本不是一个好主意。我想我必须和我的上级说话。 ;) *编辑

我在替换臃肿的If Else结构时遇到了麻烦。这是一个例子:

If ColA startswith 'ABC' then 'Ext' else
If ColB startswith 'DBC' then 'Int' else
If ColC startswith ('CCC', 'DDD','EEE', ..) then 'N/A'

....等等。

我知道我可以将其重写为Case When结构。问题是这需要存储在最大长度为nvarchar(4000)的表中。我尝试使用如下所示的查找表来解决这个问题:

lookupColumnName | lookupValue | lookupResultName | lookupResult

我试图以更“通用”的方式编写查询,如:

SELECT 
   (SELECT lookupResult from lookupTable where lookupColumn = 'ColA')
FROM
SourceTable

这是我第一次尝试实现origanel的顺序If Else结构: 的

CASE WHEN
    CASE WHEN
        CASE WHEN 
        (
        SELECT TOP 1 lookupResult FROM ##lookupDefinition where lookupColumnName = 'BKTXT' AND BKPF_BKTXT like lookupValue order by len(lookupValue) DESC 
        ) IS NULL THEN (
        SELECT TOP 1 lookupResult FROM ##lookupDefinition where lookupColumnName = 'XBLNR' AND BKPF_XBLNR like lookupValue order by len(lookupValue) DESC
        ) ELSE (
        SELECT TOP 1 lookupResult FROM ##lookupDefinition where lookupColumnName = 'BKTXT' AND BKPF_BKTXT like lookupValue order by len(lookupValue) DESC 
        ) END 
        <> 'LEER' THEN
        CASE WHEN 
        (
        SELECT TOP 1 lookupResult FROM ##lookupDefinition where lookupColumnName = 'BKTXT' AND BKPF_BKTXT like lookupValue order by len(lookupValue) DESC 
        ) IS NULL THEN (
        SELECT TOP 1 lookupResult FROM ##lookupDefinition where lookupColumnName = 'XBLNR' AND BKPF_XBLNR like lookupValue order by len(lookupValue) DESC
        ) ELSE (
        SELECT TOP 1 lookupResult FROM ##lookupDefinition where lookupColumnName = 'BKTXT' AND BKPF_BKTXT like lookupValue order by len(lookupValue) DESC 
        ) END
        ELSE
        (
        SELECT TOP 1 lookupResult FROM ##lookupDefinition where lookupColumnName = 'SGTXT' AND COEP_SGTXT like lookupValue order by len(lookupValue) DESC
        )
    END IS NULL THEN 'App'
    ELSE
    CASE WHEN
        CASE WHEN 
        (
        SELECT TOP 1 lookupResult FROM ##lookupDefinition where lookupColumnName = 'BKTXT' AND BKPF_BKTXT like lookupValue order by len(lookupValue) DESC 
        ) IS NULL THEN (
        SELECT TOP 1 lookupResult FROM ##lookupDefinition where lookupColumnName = 'XBLNR' AND BKPF_XBLNR like lookupValue order by len(lookupValue) DESC
        ) ELSE (
        SELECT TOP 1 lookupResult FROM ##lookupDefinition where lookupColumnName = 'BKTXT' AND BKPF_BKTXT like lookupValue order by len(lookupValue) DESC 
        ) END 
        <> 'LEER' THEN
        CASE WHEN 
        (
        SELECT TOP 1 lookupResult FROM ##lookupDefinition where lookupColumnName = 'BKTXT' AND BKPF_BKTXT like lookupValue order by len(lookupValue) DESC 
        ) IS NULL THEN (
        SELECT TOP 1 lookupResult FROM ##lookupDefinition where lookupColumnName = 'XBLNR' AND BKPF_XBLNR like lookupValue order by len(lookupValue) DESC
        ) ELSE (
        SELECT TOP 1 lookupResult FROM ##lookupDefinition where lookupColumnName = 'BKTXT' AND BKPF_BKTXT like lookupValue order by len(lookupValue) DESC 
        ) END
        ELSE
        (
        SELECT TOP 1 lookupResult FROM ##lookupDefinition where lookupColumnName = 'SGTXT' AND COEP_SGTXT like lookupValue order by len(lookupValue) DESC
        )
    END
END

的 但是这种方法也可能导致包含超过4000个字符的字符串。

现在我被困住了。还有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

很难遵循你的确切逻辑,因为它非常复杂,而且没有列没有表别名,所以我不知道哪个列属于哪个表。

然而,我已经开始了。由于您多次重复使用相同的相关子查询,因此将它们移动到APPLY可能会有所帮助,以便可以重用结果。然后我试着挑选你的逻辑代替如下的语句:

CASE WHEN <expression1> IS NULL THEN <expression2> ELSE <expression1> END

ISNULL(<expression1>, <expression2>)

最后查询:

SELECT  CASE WHEN ISNULL(BKTXT.LookupResult, XBLNR.LookupResult) <> 'LEER' THEN
            ISNULL(BKTXT.LookupResult, XBLNR.LookupResult)
        ELSE 
            ISNULL(SGTXT.LookupResult, 'App')
        END         
FROM    SourceTable
        CROSS APPLY 
        (   SELECT TOP 1 lookupResult 
            FROM ##lookupDefinition 
            WHERE lookupColumnName = 'BKTXT' 
            AND COEP_SGTXT LIKE lookupValue 
            ORDER BY LEN(lookupValue) DESC
        ) AS BKTXT
        CROSS APPLY 
        (   SELECT TOP 1 lookupResult 
            FROM ##lookupDefinition 
            WHERE lookupColumnName = 'XBLNR' 
            AND COEP_SGTXT LIKE lookupValue 
            ORDER BY LEN(lookupValue) DESC
        ) AS XBLNR
        CROSS APPLY 
        (   SELECT TOP 1 lookupResult 
            FROM ##lookupDefinition 
            WHERE lookupColumnName = 'SGTXT' 
            AND COEP_SGTXT LIKE lookupValue 
            ORDER BY LEN(lookupValue) DESC
        ) AS SGTXT;

答案 1 :(得分:0)

您试图使用“更通用”的方式,让我想到了这个想法:

<form class="form-horizontal">
    <h3 style="padding-left: 20px; padding-bottom: 20px">A pointless title</h3>
    <div class="row form-group">
        <div class="col-md-4">
            <label for="storeNumber" class="col-sm-4 control-label">Store Number</label>
            <div class="col-sm-6">
                <input id="storeNumber" class="form-control" type="text"
                 name="storeNumber" placeholder="Store Number" />
            </div>
        </div>
        <div class="col-md-4">
            <label for="actionedTo" class="col-sm-4 control-label">Actioned To</label>
            <div class="col-sm-6">
                <select id="actionedTo" class="form-control"></select>
            </div>
        </div>
        <div class="col-md-4">
            <label for="parentCategory" 
             class="col-sm-4 control-label">Parent Category</label>
            <div class="col-sm-6">
                <select id="parentCategory" class="form-control"></select>
            </div>
        </div>
    </div>
    <div class="row form-group">
        <div class="col-md-12">
            <label for="freeTextSearch" 
             class="col-sm-2 control-label">Free Text Search</label>
            <div class="col-sm-10">
                <input id="freeTextSearch" class="form-control" type="text"
                 name="requestNumber" placeholder="Free Text Search" />
            </div>
        </div>
    </div>       
</form>

CREATE FUNCTION dbo.GetLookUp(@LookupColumnName AS VARCHAR(100))
RETURNS VARCHAR(100)
AS
BEGIN
    DECLARE @RetVal VARCHAR(100)='#missing value!!!';
    SELECT lookupResult from lookupTable where lookupColumn = @LookupColumnName;
    RETURN @RetVal;
END

转移到

SELECT 
   (SELECT lookupResult from lookupTable where lookupColumn = 'ColA')
FROM
SourceTable

这意味着你可以节省很多角色。

但我必须承认,整个概念对我来说并不清楚,并且有很多复杂的气味。也许您想提供有关表结构,一些示例数据和预期输出的详细信息。

我很确定,有一些更好的方法......