如何在没有子查询

时间:2017-03-30 01:46:27

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

我使用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;

2 个答案:

答案 0 :(得分:1)

ORDER BY仅适用于一个SELECT,它适用于整个结果集,适用于所有行UNION后的整个结果。因此,您需要在SELECT的每个UNION ALL中添加用于排序的列。

例如,以下语法错误,因为ORDER BY必须位于SELECT的最后UNION之后。

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;

无论如何,必须在Category的每个SELECT语句中添加列UNION。我不知道你怎么能避免它。

答案 1 :(得分:0)

如果您的问题是您的排序导致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