如何在SQL中的case语句中用联接替换子选择?

时间:2019-04-16 09:41:47

标签: sql tsql join subquery

我有一个带有case语句的SQL查询。 case语句具有一个子查询。我想用联接替换(删除)子选择。有可能的?我该怎么办?

查询:

SELECT tablex.Abnumber, CASE WHEN Abdate is not null AND isnull(Abnumber,0) > 1 AND Abdate < (SELECT Abdate FROM t_tablex WHERE Annumber = @Annumber AND Abnumber= @Abnumber-1) THEN 'bla bla' ELSE '' END
FROM t_tablex AS tablex
WHERE (@Annumber IS NULL OR tablex.Annumber= @Annumber)
  AND (@AbnumberIS NULL OR tablex.Abnumber= @Abnumber)

3 个答案:

答案 0 :(得分:0)

SELECT tablex.Abnumber, 
        CASE WHEN  isnull(Abnumber,0) > 1 AND Abdate < a.Abdate THEN 'bla bla' ELSE '' END  
FROM t_tablex AS tablex 
LEFT JOIN (SELECT Abdate 
           FROM  t_tablex
           WHERE Annumber = @Annumber AND Abnumber= @Abnumber-1
) A ON A.Annumber = tablex.Annumber AND a.Abnumber = tablex.Abnumber
 WHERE tablex.Annumber= @Annumber 
AND  tablex.Abnumber= @Abnumber

答案 1 :(得分:0)

我怀疑function dumpSMSintoSender() { var MOVED_TO_SENDER = "Yes"; var userSheet = SpreadsheetApp.getActiveSpreadsheet(); var userTab = userSheet.getSheetByName('SmartCare'); var SenderTab = userSheet.getSheetByName('Sheet1'); var numRows = 200 var firstRow = 2; var range = userTab.getRange(firstRow, 3, userTab.getLastRow() - firstRow +1, 3); var data = range.getValues(); var dataRange = userTab.getRange(firstRow, 3, numRows, 10) // Fetch values for each row in the Range. var Movedata = dataRange.getValues(); for (var i = 0; i < Movedata.length; ++i) { var row = Movedata[i]; var MovedtoSender = row[5]; var sender = row[0]; var mobile = row[1]; var message = row[2]; if (mobile != "") { if (MovedtoSender != MOVED_TO_SENDER) { // Prevents sending duplicates SenderTab.getRange(SenderTab.getLastRow() + 1, 1, data.length,3).setValues(data); userTab.getRange(firstRow + i, 8).setValue("Yes"); // Make sure the cell is updated right away in case the script is interrupted SpreadsheetApp.flush(); } } } } 是您想要的:

LAG()

这与您的查询完全不同,除非对数据做出一些假设。但是,我怀疑这实际上是您想要的。

答案 2 :(得分:0)

感谢您的回答。我做了一些尝试,发现了以下解决方案:

解决方案1(用内部联接替换子选择):

SELECT tablex.Abnumber, 
    CASE WHEN tablex.Abdate is not null 
        AND isnull(tablex.Abnumber,0) > 1 
        AND tablex.Abdate < tablex2.Abdate 
    THEN 'bla bla' 
    ELSE '' END 
FROM t_tablex AS tablex
INNER JOIN t_tablex as tablex2
    ON tablex.Annumber = tablex2.Annumber
    AND tablex.Abnumber = tablex2.Abnumber + 1 
WHERE tablex.Annumber = ISNULL( @Annumber, tablex.Annumber)
AND tablex.Abnumber = ISNULL( @Abnumber, tablex.Abnumber)

解决方案2(使用LAG()):

SELECT base.*
FROM ( 
    SELECT tablex.Abnumber, 
        CASE WHEN tablex.Abdate is not null 
            AND tablex.Abnumber > 1 
            AND tablex.Abdate < LAG( tablex.Abdate, 1 ) OVER ( PARTITION BY tablex.Annumber ORDER BY tablex.Abnumber) 
        THEN 'bla bla' 
        ELSE '' END AS ERG
    FROM t_tablex AS tablex
    WHERE tablex.Annumber = ISNULL( @Annumber, tablex.Annumber )
    AND tablex.Abnumber BETWEEN ISNULL( @Abnumber , tablex.Abnumber) - 1 
    AND ISNULL( @Abnumber, tablex.Abnumber )
    ) base
WHERE
base.Abnumber = ISNULL( @Abnumber, base.Abnumber )