【问题标题】:Using correlated subquery or join instead of derived table使用相关子查询或连接而不是派生表
【发布时间】:2013-04-15 06:36:28
【问题描述】:

请考虑这种情况:

我有一张这样的桌子:

CityCode        CityName        Col_6        Col_9        Col_10
----------------------------------------------------------------------
001                London        10            21               1
001                London        24            13               2
001                London        39            10               2
002                Paris         19            61               1
002                Paris         10            50               1
003                Vien          12            41               2
004                Mosco         22            27               2
004                Mosco         28            9                2
004                Mosco         41            30               1
004                Mosco         33            12               1
005                Cairo         10            21               1
006                Milan         19            41               1
006                Milan         40            32               2

我想写一个查询来计算每个城市的一些公式。现在我使用一个游标来区分不同的城市,然后选择适当的记录并进行计算:

DECLARE mycur   CURSOR  
FOR
    SELECT CityCode
    FROM tblCities 

OPEN mycur
FETCH NEXT FROM mycur INTO @param_Code  

WHILE (@@fetch_status = 0)
BEGIN
     SELECT 
         @param_Code, (SELECT COUNT(*)
                       FROM MyTable
                       WHERE col_9 = 61
                         AND (City_Code = @param_Code) 
                      ) /
                      (SELECT COUNT(*)
                       FROM MyTable
                        AND (City_Code = @param_Code) 
                      ),
         (SELECT COUNT(*)
          FROM MyTable
          WHERE col_10 = 1
            AND (City_Code = @param_Code)) /
            (SELECT COUNT(*)
             FROM MyTable
             WHERE (col_10 = 1 OR col_10 = 2)
               AND (City_Code = @param_Code)),
         Some other calculation like above

     FETCH NEXT FROM mycur INTO @param_Code
END

CLOSE mycur
DEALLOCATE mycur

@param_Code 是我的游标变量。

我怎样才能做得更好?我不想使用派生表。我更喜欢使用相关子查询或联接。

谢谢

【问题讨论】:

    标签: sql sql-server performance sql-server-2008


    【解决方案1】:

    使用简单的GROUP BY 子句和CASE 表达式。在这种情况下,光标过多。

    SELECT CityCode, COUNT(CASE WHEN col_9 = 61 THEN 1 END) * 1.00 / COUNT(*),
                     COUNT(CASE WHEN col_10 = 1 THEN 1 END) * 1.00 
                       / COUNT(CASE WHEN (Col10 IN (1, 2)) THEN 1 END)
    FROM dbo.MyTable
    GROUP BY CityCode
    

    SQLFiddle上的演示

    如果需要进一步计算,您可以将此脚本包装在 CTE 中:

    ;WITH cte AS
     (       
      SELECT CityCode, COUNT(CASE WHEN col_9 = 61 THEN 1 END) * 1.00 / COUNT(*),
                       COUNT(CASE WHEN col_10 = 1 THEN 1 END) * 1.00 
                         / COUNT(CASE WHEN (Col10 IN (1, 2)) THEN 1 END)
      FROM dbo.MyTable
      GROUP BY CityCode
      )
      SELECT --Some other calculation like above
      FROM cte
    

    【讨论】:

      【解决方案2】:

      可能的 CTE 会帮助你 -

      ;WITH data AS 
      (
          SELECT *
          FROM dbo.MyTable t
          WHERE t.state_Code = @param_Code
      )
      SELECT 
          @param_Code 
          , result = (SELECT COUNT(1)
                      FROM data
                      WHERE col_9 = 61)
                     /
                     (SELECT COUNT(1)
                      FROM data)
      

      【讨论】:

      • 感谢@Devart。但是您的解决方案也使用光标(@param_code)。有没有没有光标的解决方案?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-10
      • 2011-11-16
      相关资源
      最近更新 更多