2

我有一个 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

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

4

2 回答 2

5

您必须使用order by才能按您想要的顺序获得结果。当没有 时,SQL 表和 SQL 结果本质上是无序的order by,除了一些特定于数据库的例外情况(例如,MySQL 保证使用时的排序group by)。

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

您可以将 替换UNIONUNION 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')

但是,我建议您保留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;
于 2013-09-02T11:42:20.393 回答
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

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

于 2013-09-02T11:38:16.747 回答