2014-09-12 66 views
1

自从为我编写T-SQL已经有一段时间了,我知道这可以完成,但是我的记忆足够让我接近(我想我很接近),但是穷人得不偿失。TSQL子查询无效列和只有一个表达式

要开始我有这个疑问:

SELECT DISTINCT(COMM_TYPE), 
     COUNT(COMM_TYPE) AS 'Total' 
    FROM 
     [MYDB].[dbo].[COMM] 
    GROUP BY 
     COMM_TYPE 

将返回:

COMM_TYPE  Total 
-------------------------- 
TypeA    1 
TypeB   44474 
TypeC    3 
TypeD   3854 
TypeE   12327 
TypeF   362912 
TypeG   484344 
TypeH    386 
TypeI    106 

这是一个正确的结果。

所以现在我想要上面加上每一个样本。与列类似:

ID  COMM_TYPE  TOTAL  DATA  COMMENTS  PRIMARY  COMM_NUMBER 

我相信这可以用一个子查询做到,但我不能正确书写它,因为我得到两个错误。

消息207,级别16,状态1,行10
无效的列名 'CT'。

消息116,级别16,状态1,行7
子查询没有引入EXISTS时,只能在选择列表中指定一个表达式。

我明白第二个错误。我的子查询有两列正在返回,但定位在选择,因为我只想要一个。

第一个错误我更迷失了。我以为我可以引用外部查询中的子查询列?

下面是该查询:

SELECT TOP(1) 
    *, 
    (SELECT 
     DISTINCT(COMM_TYPE), 
     COUNT(COMM_TYPE) 
    FROM 
     [MYDB].[dbo].[COMM] 
    GROUP BY 
     COMM_TYPE) AS CT 
FROM 
    [MYDB].[dbo].[COMM] 
WHERE 
    CT = COMM_TYPE 

这主要是为自己,但如果它可以帮助任何人在这里亚去:

我们先从(cte包住整个操作,因为它带来很多好处,但这里适用的两个是:

1.启用从标量子查询派生的列的分组 2.Referen在同一声明中多次得到表格

WITH T 
    AS (
      CTE SELECT Statement 
     ) 
FINAL SELECT Statement 

接下来我们的CTE选择基本上为我们返回三列。

1.Total这在我的查询是指望一列 2.RN这是行号 3.Wildcard *它可以获取所有列从表中现在

从这点我们进入分区....

因此,我们似乎需要选择我们如何打破这个表。由于我已经定义了DISTINCT(COMM_TYPE)而没有意识到它存在我的分区....在第一列定义中,我们也做了一个count(*)。所以必须发生的事情是,第一个SQL引擎将表分成多个部分(分区),然后对这些部分进行记录计数。

SELECT Count(*) 
    OVER (PARTITION BY COMM_TYPE) AS Total, 

接下来我们做一个ROW_NUMBER()操作OVER(又名反操作)又是我COMM_TYPE的分区...然后我们命令它和项目RN的列名....还挺不知道这是为什么需要,直到我到了最后,这是有道理的。

Row_number() 
    OVER (PARTITION BY COMM_TYPE 
    ORDER BY COMM_TYPE) AS RN, 

最后我们只是拉一个通配符,它​​是表中的每一列。

因此,在SQL引擎命名空间内存寄存器的深处,这些数据必须是相当大的一部分,这些重复的分组操作“覆盖”了所有内容。

然而,我们所看到的只是一个单行,这是因为最后一次选择,它给了我所有一切,因为我想要的东西都在一起,所以我们只得到TOP(1),因为那个RN列以前我不明白。

我理解正确吗?

+0

@Martin Smith ...您添加另一个标签的编辑可能是我需要的线索。现在将谷歌,并阅读。 – GPGVM 2014-09-12 19:27:15

+0

关于你的编辑。一个不正确的方面是,这不是一个递归CTE。如果分组有帮助的话,分区就类似于分组。 – 2014-09-12 20:24:29

+0

修正了,是的,这是有帮助的,因为我不太了解如何递归。 – GPGVM 2014-09-12 20:34:42

回答

1

这应该做你所需要的。

WITH T 
    AS (SELECT Count(*) 
        OVER (PARTITION BY COMM_TYPE) AS Total, 
       Row_number() 
        OVER (PARTITION BY COMM_TYPE 
          ORDER BY COMM_TYPE)  AS RN, 
     * 
     FROM MyDb.dbo.Comm) 
SELECT * 
FROM T 
WHERE RN = 1 
+0

确定...所以剪切并粘贴,答案奏效。谢谢!我将在这里稍微介绍一下,并刷新/重新理解正在完成的任务。 – GPGVM 2014-09-12 19:45:31

+0

@ user1278561对你来说可能有用的文章是http://sqlmag.com/database-development/optimizing-top-n-group-queries – 2014-09-12 19:49:37

相关问题