将连接添加到count()查询

时间:2011-03-14 08:45:11

标签: sql sql-server join

我从上一个问题here 获取了以下代码并稍作修改。

SELECT *
FROM ES_TOOL
  INNER JOIN ES_HARDWARE ON ES_HARDWARE.eshw_ID = ES_TOOL.ESTOOL_HARDWARE 
  INNER JOIN ES_PAYMENT  on ES_payment.espay_id = es_TOOL.estool_payment 

  LEFT JOIN (
    SELECT
      tchap.estch_tool, tfacet.estfa_tool,
      count(marks.esmrk_value) AmtMarks 
    FROM ES_MARK marks 
      left Join ES_TOOL_FACET tfacet ON marks.esmark_tool_facet = tfacet.estfa_id --line added
      left Join ES_TOOL_CHAPTER tchap ON marks.esmark_tool_chapter = tchap.estch_id 
    GROUP BY tchap.estch_tool 
  ) h  ON ES_TOOL.estool_id = h.estch_tool

我正在尝试添加一个额外的连接,以尝试从符合左连接“ON”条件的“标记”获得标记计数。如果没有额外的行执行查询,但不计算符合“facet”条件的标记。有了它我得到以下错误:

  

Msg 8120,Level 16,State 1,Line 1

     

列'ES_TOOL_FACET.estfa_tool'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。

任何帮助都将不胜感激。

4 个答案:

答案 0 :(得分:1)

错误消息表示ES_TOOL_FACET.estfa_tool需要包含在Group By中。

使用分组依据时,所有非聚合列必须包含在分组中。

答案 1 :(得分:1)

这在您的内部查询中应该是显而易见的:

SELECT  tchap.estch_tool, tfacet.estfa_tool,  count(marks.esmrk_value) AmtMarks 
FROM ES_MARK marks 
  left Join ES_TOOL_FACET tfacet ON marks.esmark_tool_facet = tfacet.estfa_id --line added
  left Join ES_TOOL_CHAPTER tchap ON marks.esmark_tool_chapter = tchap.estch_id 
GROUP BY tchap.estch_tool 

您有三个选定的列estch_tool位于GROUP BY子句中,esmrk_value位于聚合函数中,而estfa_tool位于GROUP BY中1}}子句,也不是聚合函数。

您的解决方案应该是:

  1. GROUP BY tchap.estch_tool, tfacet.estfa_tool
  2. AVG(tfacet.estfa_tool)或任何汇总功能

答案 2 :(得分:1)

此查询中存在语法错误 -

SELECT  
            tchap.estch_tool, 
            tfacet.estfa_tool,  
            count(marks.esmrk_value) AmtMarks 
        FROM ES_MARK marks   
            left Join ES_TOOL_FACET tfacet ON 
                marks.esmark_tool_facet = tfacet.estfa_id --line added  
            left Join ES_TOOL_CHAPTER tchap ON 
                marks.esmark_tool_chapter = tchap.estch_id  
        GROUP BY tchap.estch_tool  

GROUP BY要求SELECT列表中出现的任何列都应聚合或出现在GROUP BY子句中。

所以在tfacet.estfa_tool上放置一个聚合函数 - MIN,MAX,SUM,AVG等,因为它不会出现在group by子句中或包含在那里。

答案 3 :(得分:0)

我的解决方案有两种变体。哪一个更适合您,可能取决于在您试用数据时哪个会产生更好的执行计划。

变体#1的描述 :(在这两种情况下,我只描述了主SELECT的LEFT JOIN子选择背后的逻辑,实际上这部分被替换了。但是这些脚本是完整的查询,相当于你的):

  1. tools两个表中拉出和UNION所有项目。
  2. 相应地将列表加入marks表。
  3. 按工具项对结果集进行分组并获取计数。
  4. 查询:

    SELECT *
    FROM ES_TOOL
      INNER JOIN ES_HARDWARE ON ES_HARDWARE.eshw_ID = ES_TOOL.ESTOOL_HARDWARE 
      INNER JOIN ES_PAYMENT  on ES_payment.espay_id = es_TOOL.estool_payment 
    
      LEFT JOIN (
        SELECT
          tools.tool,
          COUNT(*) AS AmtMarks
        FROM (
          SELECT 'tchap'  AS tbl, estch_id AS id, estch_tool AS tool
          FROM ES_TOOL_CHAPTER
    
          UNION ALL
    
          SELECT 'tfacet' AS tbl, estfa_id AS id, estfa_tool AS tool
          FROM ES_TOOL_FACET
        ) tools
          INNER JOIN ES_MARK marks
            ON tools.tbl = 'tchap'  AND tools.id = marks.esmark_tool_chapter
            OR tools.tbl = 'tfacet' AND tools.id = marks.esmark_tool_facet
        GROUP BY tools.tool
      ) h ON ES_TOOL.estool_id = h.tool
    

    变体#2

    1. 加入ES_TOOL_CHAPTERmarks并获取所有estch_tool值,包括重复值。
    2. 同样,将ES_TOOL_FACET加入marks并获取所有estfa_tool值,并重复使用。
    3. UNION ALL两套。
    4. 按工具项对结果集进行分组并获取计数。
    5. 查询:

      SELECT *
      FROM ES_TOOL
        INNER JOIN ES_HARDWARE ON ES_HARDWARE.eshw_ID = ES_TOOL.ESTOOL_HARDWARE 
        INNER JOIN ES_PAYMENT  on ES_payment.espay_id = es_TOOL.estool_payment 
      
        LEFT JOIN (
          SELECT
            tools.tool,
            COUNT(*) AS AmtMarks
          FROM (
            SELECT estch_tool AS tool
            FROM ES_TOOL_CHAPTER tools
              INNER JOIN ES_MARK marks ON tools.estch_id = marks.esmark_tool_chapter
      
            UNION ALL
      
            SELECT estfa_tool AS tool
            FROM ES_TOOL_FACET tools
              INNER JOIN ES_MARK marks ON tools.estfa_id = marks.esmark_tool_facet
          ) tools
          GROUP BY tools.tool
        ) h ON ES_TOOL.estool_id = h.tool