如何UNION 2 CTE导致SQL

时间:2016-11-03 19:03:52

标签: sql-server tsql

- UNION给我错误

;WITH TopSelling 
AS
(
SELECT p.Name AS ProductName,SUM(LineTotal) AS TotalAmount
FROM Product AS p INNER JOIN SalesOrderDetail AS sod
ON p.ProductID = sod.ProductID
GROUP BY p.Name
)


SELECT ProductName, TotalAmount
FROM TopSelling
ORDER BY TotalAmount DESC
OFFSET 0 ROWS
FETCH NEXT 5 ROWS ONLY


UNION ALL

SELECT 'Grand Total' AS ProductName, sum(TotalAmount) AS TotalAmount
FROM TopSelling

3 个答案:

答案 0 :(得分:2)

    ;WITH TopSelling 
    AS
    (
         SELECT p.Name AS ProductName,SUM(LineTotal) AS TotalAmount
         FROM Product AS p INNER JOIN SalesOrderDetail AS sod
         ON p.ProductID = sod.ProductID
         GROUP BY p.Name
    ),
    topSelling1 as 
    (
         SELECT ProductName, TotalAmount
         FROM TopSelling
         ORDER BY TotalAmount DESC
         OFFSET 0 ROWS
         FETCH NEXT 5 ROWS ONLY
    ),
    total as
    (
         SELECT sum(TotalAmount) AS TotalAmount
         FROM TopSelling;
    )
    select ProductName, TotalAmount
    FROM TopSelling1
    UNION ALL
    SELECT 'Grand Total' AS ProductName, TotalAmount
    FROM Total;

答案 1 :(得分:1)

所以不要使用它。请改用GROUPING SETS

SELECT COALESCE(p.Name, 'Grand Total') AS ProductName,  -- The lazy way
       SUM(LineTotal) AS TotalAmount
FROM Product p INNER JOIN
     SalesOrderDetail sod
     ON p.ProductID = sod.ProductID
GROUP BY GROUPING SETS ( (p.Name), () )
ORDER BY TotalAmount DESC;

编辑:

哦,我知道,你想要前五行然后总计。

使用子查询:

WITH TopSelling AS
     (SELECT p.Name as ProductName, SUM(LineTotal) as TotalAmount
      FROM Product p INNER JOIN
          SalesOrderDetail sod
          ON p.ProductID = sod.ProductID
      GROUP BY p.Name
    )
SELECT ProductName, TotalAmount
FROM ((SELECT TOP 5 ProductName, TotalAmount, 1 as Priority
       FROM TopSelling
       ORDER BY TotalAmount DESC
      ) UNION ALL
      (SELECT 'Grand Total' AS ProductName, sum(TotalAmount) AS TotalAmount, 2 as Priority
       FROM TopSelling
      )
     ) t
ORDER BY Priority, TotalAmount DESC;

在这种情况下,我发现TOP 5OFFSET / FETCH更自然。当然,后者对传呼更为明智。

答案 2 :(得分:0)

从第二个选择中删除别名

;WITH TopSelling 
AS
(
SELECT p.Name AS ProductName,SUM(LineTotal) AS TotalAmount
FROM Product AS p INNER JOIN SalesOrderDetail AS sod
ON p.ProductID = sod.ProductID
GROUP BY p.Name
)

  SELECT ProductName, TotalAmount
  FROM TopSelling
  ORDER BY TotalAmount DESC
  OFFSET 0 ROWS
  FETCH NEXT 5 ROWS ONLY

  UNION ALL

  SELECT 'Grand Total' , sum(TotalAmount)
  FROM TopSelling