使用GROUP BY对行中列的值求和

时间:2018-09-10 15:53:34

标签: sql-server

我有一个包含以下字段的表;

id (int)
line_id (int)
cell_no (int)
timestamp (datetime)
total (int)
passed (int)
data_type (varchar)
created_at (datetime)
updated_at (datetime)

在该表中,有多个行包含相同值的cell_no。我想查询表,用相同的cell_no值合并所有行,对每个不同的cell_no传递的总数和总数求和,然后返回按传递的总数/总数按升序排序的结果。

我可以在MySQL中正常工作,但不能在MSSQL中工作,因为它抱怨某些字段不是按定义分组的,而是当我将它们放在分组时的行。 cell_no是相同的,不会合并。

这是我在MySQL中进行查询的方式;

SELECT id, cell_no, data_type, sum(total) AS total, sum(passed) AS passed
FROM line_data AS ld
WHERE line_id = 1
      AND timestamp >= '2018-07-29 00:00:00'
      AND timestamp <= '2018-07-29 23:00:00'
GROUP BY cell_no
ORDER BY ((passed / total) * 100) ASC

如何将其呈现给MSSQL?

3 个答案:

答案 0 :(得分:2)

您的问题是您的查询是无效的SQL。每个cell_no都有多个iddata_type,您不会告诉DBMS选择哪个。

MySQL默默地将您的select子句转换为

SELECT
  ANY_VALUE(id),
  cell_no,
  ANY_VALUE(data_type),
  SUM(total) AS total,
  SUM(passed) AS passed

函数ANY_VALUE(id)表示您不必关心要为结果选择哪个cell_no的ID。

ANY_VALUE在SQL Server中不可用,但是由于您显然不在乎哪个值,因此可以将其替换为MINMAX

SELECT
  MIN(id),
  cell_no,
  MIN(data_type),
  SUM(total) AS total,
  SUM(passed) AS passed

更新:另一个问题可能是您的ORDER BY子句。 7/2在MySQL中是3.5(应该可以预料),但在SQL Server中只有3,因为SQL Server看到两个整数的除法,并且也希望结果是整数。您可以将一个或两个整数转换为十进制以获得十进制结果:

ORDER BY (CAST(passed AS DECIMAL) / total) * 100 ASC

答案 1 :(得分:1)

您有两个错误:

  • 您只能选择在分组依据上聚合或指定的字段。
  • 您必须按订单汇总/求和。

您有三种方法可以修复它们。

  1. 从选择中删除id

    SELECT cell_no, SUM(total) AS total, SUM(passed) AS passed
    FROM line_data AS ld
    WHERE line_id = 1
      AND timestamp >= '2018-07-29 00:00:00'
      AND timestamp <= '2018-07-29 23:00:00'
    GROUP BY cell_no
    ORDER BY ((SUM(passed)/ SUM(total)) * 100) ASC
    
  2. 在您的id中添加group by列:

    SELECT 
        id, cell_no, data_type, 
        SUM(total) AS total, SUM(passed) AS passed
    FROM line_data AS ld
    WHERE line_id = 1
      AND timestamp >= '2018-07-29 00:00:00'
      AND timestamp <= '2018-07-29 23:00:00'
    GROUP BY id, cell_no, data_type
    ORDER BY ((SUM(passed) / SUM(total)) * 100) ASC
    
  3. 汇总id列(包含max,min或...。)

    SELECT 
        MAX(id), cell_no, data_type, 
        SUM(total) AS total, SUM(passed) AS passed
    FROM line_data AS ld
    WHERE line_id = 1
      AND timestamp >= '2018-07-29 00:00:00'
      AND timestamp <= '2018-07-29 23:00:00'
    GROUP BY cell_no, data_type
    ORDER BY ((SUM(passed)/ SUM(total)) * 100) ASC
    

答案 2 :(得分:0)

Select语句中未聚合的所有字段都必须位于“分组依据”中。

SELECT id, cell_no, data_type, sum(total) AS total, sum(passed) AS passed, (sum(passed)/sum(total)*100) as percent_passed FROM line_data AS ld WHERE line_id = 1 AND timestamp >= '2018-07-29 00:00:00' AND timestamp <= '2018-07-29 23:00:00' GROUP BY id, cell_no, data_type ORDER BY 6 ASC

经过编辑以包括在select语句中传递的百分比,然后按6排序以按列6排序。