如何订购使用UNION的SQL查询,以便按查询所在的顺序返回数据?

Tan*_*ilo 2 sql oracle

我有一个SQL查询,沿着以下几行:

SELECT R.NUMERIC_VAL, 'A'  /* query A */
  FROM TABLE_1  
 WHERE TABLE_1.DATE = TO_DATE('04/04/2012', 'DD/MM/YYYY') 
 UNION
SELECT E.NUMBER_VALUE, 'B' /* query B */
  FROM TABLE_2 
 WHERE TABLE_2.DATE = TO_DATE('05/04/2012', 'DD/MM/YYYY')
 UNION
SELECT E.OTHER_NUMBER_VALUE, 'C' /* query C */
  FROM TABLE_2
 WHERE TABLE_2.DATE = TO_DATE('05/04/2012', 'DD/MM/YYYY')
 ORDER BY 2
Run Code Online (Sandbox Code Playgroud)

如您所见,我当前的解决方案取回字母A,B和C,并按第二列排序查询.我知道这个查询总是会为每个查询返回1行.我想知道是否有任何方法可以使查询按照查询当前写入的顺序恢复数据,而不必使用第二列?谢谢.

Jan*_*net 5

SELECT NumVal FROM
(
    SELECT R.NUMERIC_VAL AS NumVal, 1 AS queryNo
    FROM TABLE_1  
    WHERE TABLE_1.DATE = TO_DATE('04/04/2012', 'DD/MM/YYYY') 
    UNION
    SELECT E.NUMBER_VALUE AS NumVal, 2 AS queryNo
    FROM TABLE_2 
    WHERE TABLE_2.DATE = TO_DATE('05/04/2012', 'DD/MM/YYYY')
    UNION
    SELECT E.OTHER_NUMBER_VALUE AS NumVal, 3 AS queryNo
    FROM TABLE_2
    WHERE TABLE_2.DATE = TO_DATE('05/04/2012', 'DD/MM/YYYY')
) T
ORDER BY queryNo ASC
Run Code Online (Sandbox Code Playgroud)

虽然我没有看到一种方法可靠地做到这一点没有假的第二列,但这种方式至少它不是结果的一部分.您也可以尝试使用UNION ALL,这意味着它不必消除重复值,可能保留顺序,但正如我所说,可能不可靠.


Gor*_*off 5

您必须使用order by按所需顺序获取结果.order by除非有一些特定于数据库的异常(例如,MySQL在使用时保证排序group by),否则SQL表和SQL结果本身就是无序的.

UNION并且UNION ALL不保证结果的排序.实际上,在许多数据库中,UNION将按字母顺序(通过第一列)返回结果,作为重复删除过程的一部分.

你可以替换UNION使用UNION ALL.虽然不能保证按特定顺序返回结果,但通常会按照写入的顺序返回结果:

SELECT R.NUMERIC_VAL, 'A'  /* query A */
FROM TABLE_1  
WHERE TABLE_1.DATE = TO_DATE('04/04/2012', 'DD/MM/YYYY') 
UNION ALL
SELECT E.NUMBER_VALUE, 'B' /* query B */
FROM TABLE_2 
WHERE TABLE_2.DATE = TO_DATE('05/04/2012', 'DD/MM/YYYY')
UNION ALL
SELECT E.OTHER_NUMBER_VALUE, 'C' /* query C */
FROM TABLE_2
WHERE TABLE_2.DATE = TO_DATE('05/04/2012', 'DD/MM/YYYY')
Run Code Online (Sandbox Code Playgroud)

但是,我建议你保留ORDER BY.

如果您不想要第二列,请使用子查询:

select NUMERIC_VAL
from (SELECT R.NUMERIC_VAL, 'A' as ordering /* query A */
      FROM TABLE_1  
      WHERE TABLE_1.DATE = TO_DATE('04/04/2012', 'DD/MM/YYYY') 
      UNION ALL
      SELECT E.NUMBER_VALUE, 'B' /* query B */
      FROM TABLE_2 
      WHERE TABLE_2.DATE = TO_DATE('05/04/2012', 'DD/MM/YYYY')
      UNION ALL
      SELECT E.OTHER_NUMBER_VALUE, 'C' /* query C */
      FROM TABLE_2
      WHERE TABLE_2.DATE = TO_DATE('05/04/2012', 'DD/MM/YYYY')
     ) t
ORDER BY ordering;
Run Code Online (Sandbox Code Playgroud)