每次在子查询中执行许多复杂的处理和许多列 SELECT 时,都会遇到此问题,但最终只需要显示很少的内容即可。 无论如何,SQL(Oracle或Microsoft或其他公司)是否正在考虑使用(extra)子句以忽略不需要的列。
;with t as (
select col1, col2, col3, col4, col5, col6, col7, col8, col9, col10
from orders_tbl
where order_date > getdate() -- ex. T-sql
)
, s as (
select t.*, row_number() over(partition by col1 order by col8 DESC, col9) rn
from t
)
--
-- The problem is here: if i don't explicitly select the individual columns of "t" ,then it'll display the column "rn" as well which is not required.
--
select col1, col2, col3, col4, col5, col6, col7, col8, col9, col10
from s where rn = 1
order by col1, col2
现在,想象这样的事情-
with t as (
select col1, col2, col3, col4, col5, col6, col7, col8, col9, col10
from orders_tbl
where order_date > getdate() -- ex. T-sql
)
, s as (
select t.*, row_number() over(partition by col1 order by col8 DESC, col9) rn
from t
)
--
-- Note: the imaginary clause "exclude"
--
select *
from s exclude (rn) where rn = 1
order by col1, col2
请问您的想法?
答案 0 :(得分:4)
如果MS Sql Server支持Google BigQuery之类的SELECT * EXCEPT col FROM tbl
之类,那就太好了。
但是,目前尚未在MS Sql Server中实现该功能。
但是,可以简化该SQL。并且仅使用1 CTE。
由于TOP 1 WITH TIES可以与ORDER BY ROW_NUMBER() OVER (...)
结合使用。
这样,您就没有RN列要从最终结果中排除。
with T as (
select TOP 1 WITH TIES
col1, col2, col3, col4, col5, col6, col7, col8, col9, col10
from orders_tbl
where order_date > getdate()
ORDER BY row_number() over(partition by col1 order by col8 DESC, col9)
)
select *
from T
order by col1, col2;
请注意,此处仅需要CTE,因为最终结果仍然必须由col1,col2排序。
旁注一:
对于简单查询,似乎更经常使用外部查询中的必填字段。
with CTE as (
select *
, row_number() over(partition by col1 order by col8 DESC, col9) as rn
from orders_tbl
where order_date > getdate()
)
select col1, col2, col3, col4, col5, col6, col7, col8, col9, col10
from CTE
where rn = 1
order by col1, col2;
旁注二:
我很想看到有一天在SQL标准中添加了类似TeraData的QUALIFY子句。当需要基于窗口函数(如ROW_NUMBER或DENSE_RANK)进行过滤时,这是一件好事。
在TeraData中,SQL可以像这样被高尔夫编码:
select col1, col2, col3, col4, col5, col6, col7, col8, col9, col10
from orders_tbl
where order_date > current_timestamp
QUALIFY row_number() over(partition by col1 order by col8 DESC, col9) = 1
order by col1, col2
答案 1 :(得分:0)
一种方法是先select into
个新表,然后再drop
列:
select col1, col2, col3, col4, col5, col6, col7, col8, col9, col10, row_number() over(partition by col1 order by col8 DESC, col9) rn
into #a
from orders_tbl
where order_date > getdate()
alter table #a drop column col1
select * from #a
请注意,这并不是最佳性能,因为您已经阅读然后删除了一些数据。但这对于很少的数据和即时查询非常方便。