7

我有 SQL 查询,我想在结果中添加插入空白行,以便轻松查看结果。我想在 ORDER BY 之后插入它。不知道能不能做到。

这是我的选择声明。

SELECT TableName.CREWACTIONFACTID
      ,TableName.CREWKEY as CrewKey
      ,TableName.EVENTKEY as EventID
      ,TableName.ACTIONSEQUENCE
      ,case TableName.ACTIONTYPE
            when 'DISPATCHED' then '2-Dispatched'
            when 'ASSIGNED' then '1-Assigned'
            when 'ENROUTE' then '3-Entoute'
            when 'ARRIVED' then '4-Arrived'
            else 'unknown'
            end  as Type
      ,TableName.STARTDATETIME as StartTime
      ,TableName.ENDDATETIME as EndTIme
      ,TableName.DURATION as Duration

  FROM DatabaseName.TableName TableName
  where 
    To_Date(to_char(TableName.STARTDATETIME, 'DD-MON-YYYY')) >= To_Date('?DATE1::?','MM/DD/YYYY')
    AND To_Date(to_char(TableName.ENDDATETIME, 'DD-MON-YYYY')) <= To_Date('?DATE2::?','MM/DD/YYYY')
   ORDER BY TableName.EVENTKEY, TableName.STARTDATETIME,TableName.ACTIONSEQUENCE
4

4 回答 4

6

你可以,就像 Michael 和 Gordon 所做的那样,在 上添加一个空行union all,但你需要在 之前有它order by

...
and to_date(to_char(t.enddatetime, 'DD-MON-YYYY')) <=
    to_date('?DATE2::?','MM/DD/YYYY')
union all
select null, null, null, null, null, null, null, null
from dual
order by eventid, starttime, actionsequence;

...并且您不能case直接使用 Gordon 在中的那个,order by因为它不是一个选定的值——您将得到一个 ORA-07185。(请注意, 中的列名是您在 中分配order by别名select,而不是表中的别名;并且您不包括表名/别名;并且没有必要为null联合部分中的列设置别名,但为了清楚起见,您可能需要这样做)。

但这依赖于null在任何实际值之后进行排序,这可能并非总是如此(不确定,但可能会受到 NLS 参数的影响),并且不知道实际eventkey是否永远存在null。因此,在查询的两个部分中引入一个虚拟列并将其用于排序可能更安全,但通过嵌套查询将其从结果中排除:

select crewactionfactid, crewkey, eventid, actionsequence, type,
    starttime, endtime, duration
from (
    select 0 as dummy_order_field,
        t.crewactionfactid,
        t.crewkey,
        t.eventkey as eventid,
        t.actionsequence,
        case t.actiontype
            when 'DISPATCHED' then '2-Dispatched'
            when 'ASSIGNED' then '1-Assigned'
            when 'ENROUTE' then '3-Enroute'
            when 'ARRIVED' then '4-Arrived'
            else 'unknown'
        end as type,
        t.startdatetime as starttime,
        t.enddatetime as endtime,
        t.duration
    from schema_name.table_name t
    where to_date(to_char(t.startdatetime, 'DD-MON-YYYY')) >=
        to_date('?DATE1::?','MM/DD/YYYY')
    and to_date(to_char(t.enddatetime, 'DD-MON-YYYY')) <=
        to_date('?DATE2::?','MM/DD/YYYY')
    union all
    select 1, null, null, null, null, null, null, null, null
    from dual
)
order by dummy_order_field, eventid, starttime, action sequence;

不过,日期处理很奇怪,尤其是to_date(to_char(...))零件。看起来您只是想丢失时间部分,在这种情况下,您可以trunk改用:

where trunc(t.startdatetime) >= to_date('?DATE1::?','MM/DD/YYYY')
and trunc(t.enddatetime) <= to_date('?DATE2::?','MM/DD/YYYY')

但是将任何函数应用于日期列会阻止使用任何索引,所以最好不要管它,让变量部分处于正确的状态以进行比较:

where t.startdatetime >= to_date('?DATE1::?','MM/DD/YYYY')
and t.enddatetime < to_date('?DATE2::?','MM/DD/YYYY') + 1

增加了+ 1一天,所以 idDATE207/12/2012,过滤器是< 2012-07-13 00:00:00,与 相同<= 2012-07-12 23:59:59

于 2012-07-12T08:14:58.430 回答
3

你的问题比较复杂。SQL 仅通过 order by 保证结果的排序。它不保证之后会发生什么。因此,您必须放入空白行,然后添加信息后记:

<your select query minus the order by>
union all
select NULL as CrewActionFatId, . . .
order by (case when CrewActionFactId is NULL then 1 else 0 end),
         TableName.EVENTKEY, TableName.STARTDATETIME,TableName.ACTIONSEQUENCE

在实践中,@Michael 的解决方案通常会起作用。但不能保证。

此外,您应该决定是否需要空白或 NULL。我猜第一个 id 是一个数字,所以我将它设置为 NULL。

通常,此类表示细节由调用应用程序处理。也许您需要更好的 SQL 查询工具来更清晰地查看数据。

这是完整查询的样子(所有字段都设置为 NULL,如果您愿意,可以将其更改为空白):

SELECT TableName.CREWACTIONFACTID, TableName.CREWKEY as CrewKey,
       TableName.EVENTKEY as EventID, TableName.ACTIONSEQUENCE,
       (case TableName.ACTIONTYPE
            when 'DISPATCHED' then '2-Dispatched'
            when 'ASSIGNED' then '1-Assigned'
            when 'ENROUTE' then '3-Entoute'
            when 'ARRIVED' then '4-Arrived'
            else 'unknown'
        end) as Type,
       TableName.STARTDATETIME as StartTime,
       TableName.ENDDATETIME as EndTIme,
       TableName.DURATION as Duration
FROM DatabaseName.TableName TableName
where To_Date(to_char(TableName.STARTDATETIME, 'DD-MON-YYYY')) >= To_Date('?DATE1::?','MM/DD/YYYY') AND
      To_Date(to_char(TableName.ENDDATETIME, 'DD-MON-YYYY')) <= To_Date('?DATE2::?','MM/DD/YYYY')
union all
SELECT NULL AS CREWACTIONFACTID, NULL AS CrewKey, NULL AS EventID,
       NULL AS ACTIONSEQUENCE, NULL AS Type, NULL AS StartTime, NULL AS EndTime,
       NULL AS Duration
from dual
ORDER BY (case when CrewActionFactId is NULL then 1 else 0 end),
         TableName.EVENTKEY, TableName.STARTDATETIME, TableName.ACTIONSEQUENCE 
于 2012-07-11T16:14:50.867 回答
2

可以肯定的是,这是一个奇怪的请求,但是可以通过UNION对一行文字空白值进行 a 来完成。为确保 order-by 应用于实际查询,请将整个内容包含在()其中,然后将其与空白行合并。

SELECT * FROM
(SELECT TableName.CREWACTIONFACTID
  ,TableName.CREWKEY as CrewKey
  ,TableName.EVENTKEY as EventID
  ,TableName.ACTIONSEQUENCE
  ,case TableName.ACTIONTYPE
        when 'DISPATCHED' then '2-Dispatched'
        when 'ASSIGNED' then '1-Assigned'
        when 'ENROUTE' then '3-Entoute'
        when 'ARRIVED' then '4-Arrived'
        else 'unknown'
        end  as Type
  ,TableName.STARTDATETIME as StartTime
  ,TableName.ENDDATETIME as EndTIme
  ,TableName.DURATION as Duration
FROM DatabaseName.TableName TableName
where 
To_Date(to_char(TableName.STARTDATETIME, 'DD-MON-YYYY')) >= To_Date('?DATE1::?','MM/DD/YYYY')
AND To_Date(to_char(TableName.ENDDATETIME, 'DD-MON-YYYY')) <= To_Date('?DATE2::?','MM/DD/YYYY')
ORDER BY TableName.EVENTKEY, TableName.STARTDATETIME,TableName.ACTIONSEQUENCE
)
UNION ALL
SELECT 
  '' AS CREWACTIONFACTID,
  '' AS CrewKey,
  '' AS EventID,
  '' AS ACTIONSEQUENCE,
  '' AS Type,
  '' AS StartTime,
  '' AS EndTime,
  '' AS Duration
FROM dual

最后,根据您呈现此结果的方式,我会研究其他分隔结果的方法。将空白行附加到查询中以用于表示目的是在业务和表示逻辑分离的情况下进行的。

于 2012-07-11T16:09:52.317 回答
1

结果将显示在 HTML 页面中。

因此,使用 SQL 来提取数据,而不是格式化输出。根据页面结构和布局,有很多解决方案。看看这里

于 2012-07-11T19:17:26.090 回答