【问题标题】:Getting count of records in child table using select statement使用 select 语句获取子表中的记录数
【发布时间】:2013-05-09 18:12:37
【问题描述】:

我有一个存储过程,我试图在其中选择表表 1 的所有列。还有另一个表使用表 1 主键作为外键。我想用这样的选择来计算这个外键表中的记录数:

SELECT *, count(*) VacancyCount
    FROM Table1 hc
    LEFT JOIN Table2 hv
    on hc.CompanyID = hv.CompanyID  
    WHERE hc.Deleted = 0
    group by hc.CompanyID
    ORDER BY NameLang1

但它给出了错误:

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

请建议如何解决这个问题?

【问题讨论】:

    标签: sql sql-server sql-server-2008 tsql sql-server-2008-r2


    【解决方案1】:

    请尝试:

    select 
        *,
        (select COUNT(*) from Table2 hv where hv.CompanyID=hc.CompanyID) VacancyCount
    from Table1 hc
    where
        hc.Deleted = 0
    order by hc.NameLang1, VacancyCount desc
    

    使用新列进行排序

    select * from(
        select 
            *,
            CONVERT(NVARCHAR(100), (select COUNT(*) from Table2 hv where hv.CompanyID=hc.CompanyID)) VacancyCount
        from Table1 hc
        where
            hc.Deleted = 0
    )x
    Order by CASE WHEN @OrderByParam = 1 THEN NameLang1 ELSE VacancyCount END
    

    提供的列 NameLang1VacancyCount 具有相同的数据类型。

    【讨论】:

    • 我们可以使用 count 按结果排序吗?
    • 是的......当然......你可以添加VacancyCount descVacancyCount asc
    • techdo:我正在尝试这个 Order by CASE WHEN @OrderByParam = 1 THEN NameLang1 ELSE VacancyCount END 但它说无效列 VacancyCount
    • 在 case 条件中,你不会得到别名列名VacancyCount。为此,您需要将其作为一个块。
    • 我使用了它,但它显示:消息 245,级别 16,状态 1,过程 hr_Companies_GetList,第 13 行将 nvarchar 值“my company1aa”转换为数据类型 int 时转换失败。我看到我的 company1aa 是按子句 NameLang1 顺序使用的列的值
    【解决方案2】:

    您的分组错误。您需要在 SELECT 而不是 '*' 和 GROUP BY 子句中使用表 1 中的所有列。

    或者您可以尝试不同的方法,如下所示:

    SELECT *
    FROM Table1 hc
    LEFT JOIN (SELECT CompanyID, COUNT(*) cnt FROM Table2 GROUP BY CompanyID) hv
    on hc.CompanyID = hv.CompanyID  
    WHERE hc.Deleted = 0
    ORDER BY NameLang1
    

    【讨论】:

    • 我们可以使用 cnt 按结果排序吗?
    • 当然,包裹成子查询后变成普通列,可以在任何子句中使用(包括order by)。
    • 我使用的是 techdo 答案,但是当我使用 Order by CASE WHEN @OrderByParam = 1 THEN NameLang1 ELSE VacancyCount END 它说无效列 VacancyCount
    • 因为它不在他的答案中的子查询(别名)中,但在我的答案中,这就是为什么你会遇到异常。 Oracle 在完成查询之前不知道列名(读取别名),并且由于子查询在主查询之前执行,因此允许在 order by 子句中使用子查询中使用的别名作为表列的名称。
    • 顺便说一下,@techdo 建议的方式在性能方面效率不高,对于 Table1 中的每一行执行一个子查询,但在我的示例中只有一个子查询执行和一个更快的连接操作。
    【解决方案3】:

    您必须列出 GROUP BY 子句中的每一列
    这些列是SELECT * 位中的列。

    无论如何这都是正确的 ANSI SQL。

    SELECT * 本身就是不好的:明确列出列总是更好

    【讨论】:

      【解决方案4】:

      尝试以这种方式在 group by 中包含列列表

       SELECT column1,column2,column3..,NameLang1,count(*) VacancyCount
      FROM Table1 hc
      LEFT JOIN Table2 hv
      on hc.CompanyID = hv.CompanyID  
      WHERE hc.Deleted = 0
      group by column1,column2,column3
      ORDER BY NameLang1
      

      【讨论】:

        猜你喜欢
        • 2020-03-11
        • 1970-01-01
        • 2011-12-06
        • 1970-01-01
        • 2022-06-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-10
        相关资源
        最近更新 更多