【问题标题】:How to ORDER BY one query only in a UNION ALL without subquery如何仅在没有子查询的 UNION ALL 中按一个查询排序
【发布时间】:2017-03-30 01:46:26
【问题描述】:

我正在使用 UNION ALL 从不相关的数据创建一个列表,以便在 SQL Server 2008 中保存到 Excel。只有一个 SELECT 语句将具有 ORDER BY,这就是我的问题出现的地方以下错误信息

'The multi-part identifier "p.Category" could not be bound.'

这是一个简化的工作代码示例,我更喜欢下面的第二个,但在取消注释第一个 SELECT 查询时会中断:

CREATE TABLE #People(Category varchar(50), [Name] varchar(50));

INSERT INTO #People VALUES(1, 'Steve');
INSERT INTO #People VALUES(99, 'Anna');
INSERT INTO #People VALUES(2, 'Sarah'); 

-- Unrelated data SELECT query
--SELECT 'Best Employee' AS Matrix
--     , 'Alan' AS [Name]
--UNION ALL

SELECT CASE
           WHEN p.Category = 1
           THEN 'Very Active'
           WHEN p.Category = 2
           THEN 'Active '
           ELSE 'Departed'
       END AS Matrix
     , p.name AS [Name]
FROM #People p
ORDER BY p.Category;

DROP TABLE #People;

经过一些研究,我发现我可以通过以下方式重写查询,这将在这个小示例中为我提供所需的结果,但在我的实际案例中我认为这不是理想的结果。有没有办法给我正确的结果,而无需像下面的工作示例中那样使用子查询?

CREATE TABLE #People(Category varchar(50), [Name]  varchar(50));

INSERT INTO #People VALUES(1, 'Steve');
INSERT INTO #People VALUES(99, 'Anna');
INSERT INTO #People VALUES(2, 'Sarah'); 

SELECT *
FROM
(
    -- Unrelated data SELECT query
    SELECT 'Best Employee' AS Matrix
         , 'Alan' AS [Name]
         , '' AS Category

    UNION ALL

    SELECT CASE
               WHEN p.Category = 1
               THEN 'Very Active'
               WHEN p.Category = 2
               THEN 'Active '
               ELSE 'Departed'
           END Matrix
         , p.name AS [Name]
         , p.Category Category
    FROM #People p
) x
ORDER BY x.Category;

DROP TABLE #People;

【问题讨论】:

    标签: sql sql-server sql-server-2008 sql-order-by union-all


    【解决方案1】:

    ORDER BY 不仅仅适用于一个SELECT,它适用于整个结果集,适用于所有行都经过UNIONed 之后的整个结果。因此,您需要在UNION ALL 的每个SELECT 中包含将用于排序的列。

    例如,以下是错误的语法,因为ORDER BY 必须在UNION 的最后一个SELECT 之后。

    SELECT CASE
               WHEN p.Category = 1
               THEN 'Very Active'
               WHEN p.Category = 2
               THEN 'Active '
               ELSE 'Departed'
           END AS Matrix
         , p.name AS [Name]
    FROM #People p
    ORDER BY p.Category
    
    UNION ALL
    
    SELECT 'Best Employee' AS Matrix
         , 'Alan' AS [Name]
    

    问题中的第二个示例可以用更简单的形式编写,没有子查询:

    SELECT CASE
               WHEN p.Category = 1
               THEN 'Very Active'
               WHEN p.Category = 2
               THEN 'Active '
               ELSE 'Departed'
           END AS Matrix
         , p.name AS [Name]
         , p.Category
    FROM #People p
    
    UNION ALL
    
    SELECT 'Best Employee' AS Matrix
         , 'Alan' AS [Name]
         , NULL AS Category  --- or '' AS Category
    
    ORDER BY Category;
    

    在任何情况下,都必须在UNION 的每个SELECT 语句中添加Category 列。我不知道你怎么能避免它。

    【讨论】:

      【解决方案2】:

      如果您的问题是您的排序导致 2 个表混淆,您可以添加一列,以便始终首先显示第一个选择结果集。

      CREATE TABLE #People(Category varchar(50), [Name]  varchar(50));
      
      INSERT INTO #People VALUES(1, 'Steve');
      INSERT INTO #People VALUES(99, 'Anna');
      INSERT INTO #People VALUES(2, 'Sarah'); 
      
      SELECT Matrix, Name, Category
      FROM
      (
          -- Unrelated data SELECT query
          SELECT 'Best Employee' AS Matrix
               , 'Alan' AS [Name]
               , '' AS Category
               , 1 as Ord
      
      UNION ALL
      
          SELECT CASE
                     WHEN p.Category = 1
                     THEN 'Very Active'
                     WHEN p.Category = 2
                     THEN 'Active '
                     ELSE 'Departed'
                 END Matrix
               , p.name AS [Name]
               , p.Category Category,
               2 as Ord
          FROM #People p
      ) x
      ORDER BY x.Ord --,Additional Order by columns
      

      【讨论】:

      • 我真正担心的不是顺序,而是SELECT 语句的绝对数量。我的希望是只需要更改 ORDER BY 的声明,并让所有其他人保持原样。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-07
      • 2018-07-27
      相关资源
      最近更新 更多