【问题标题】:SQL Server : show a new column that does calculation base on other rowsSQL Server:显示一个基于其他行进行计算的新列
【发布时间】:2017-01-25 04:46:47
【问题描述】:

我正在使用 SQL Server,我有一个表,我已简化如下:

item ----- order-----Active
-------------------------------    
a-------------1---------true
b-------------2---------false
c-------------3---------true
d-------------4---------true
e-------------5---------false
f-------------6---------true

我想查询返回三列和一个额外的列调用 new-order,对于每个订单号低于自身的非活动(活动为假)项目,它减去一个。所以上表会变成

item ----- ordering-----Active----------NewOrder
-------------------------------------------------    
a-------------1---------true----------1
b-------------2---------false----------2
c-------------3---------true----------2
d-------------4---------true----------3
e-------------5---------false----------4
f-------------6---------true----------4

我的尝试:

Select 
    g.item, g.ordering, g.active,  
    g.ordering - (Select Count(x.ordering)
                  from grocery As x
                  where x.ordering < g.ordering 
                    and x.active = false
                  group by x.ordering) As NewOrder
 From 
     grocery as g

这不起作用,因为子查询包含不止一行。但老实说,我不知道如何处理这个问题。这甚至可以仅使用子查询吗?

感谢任何建议或帮助

编辑:

在数据库中有超过 6 行,并且顺序不正确。 基本上,一个项目的新订单是它自己的 ordering# 减去 ordering# 低于项目 ordering# 的非活动项目的数量。 同样,非活动项目是 active = false 的项目。

【问题讨论】:

  • 您的预期输出似乎与您的逻辑不一致。
  • 考虑使用JOIN
  • 如果你真的想要order - 1,你可以这样做。但是,听起来您可能想要以前的顺序(基于数字顺序),而且我猜,您不能保证顺序是顺序的。这是一个逻辑上的飞跃,但它足够普遍,也许是真的?
  • 我在最后添加了另一个解释。希望它能消除混乱
  • 看看我的回答是否有帮助

标签: sql sql-server


【解决方案1】:

我认为下面的查询会给你你想要的结果,你可以省略NULL 值。 当activetrue 时,您基本上想要NEWORDER,因此您可以省略falseNULL

select
a.*,
b.NEWORDER
from
(
select
*
from
test1
)
as a
left join
(
    select [order] as NO,ROW_NUMBER() over(order by [order]) as NEWORDER from test1 where active='true'
)
as b
on a.[order]=b.no

输出

 item   order   active  NEWORDER
-------------------------------------
a       1       true    1
b       2       false   NULL
c       3       true    2
d       4       true    3
e       5       false   NULL
f       6       true    4

【讨论】:

    【解决方案2】:

    这是一种方法

    SELECT item,
           [order],
           active,
           NewOrder = Sum(t)OVER(ORDER BY [order]) 
    FROM   (SELECT *,
                   CASE WHEN Lag(Active)OVER(ORDER BY [order]) = 'false' THEN 0 ELSE 1 END AS t
            FROM   (VALUES ('a',1,'true' ),
                           ('b',2,'false' ),
                           ('c',3,'true' ),
                           ('d',4,'true' ),
                           ('e',5,'false' ),
                           ('f',6,'true' )) tc (item, [order], Active)) a 
    

    结果:

    +------+-------+--------+----------+
    | item | order | active | NewOrder |
    +------+-------+--------+----------+
    | a    |     1 | true   |        1 |
    | b    |     2 | false  |        2 |
    | c    |     3 | true   |        2 |
    | d    |     4 | true   |        3 |
    | e    |     5 | false  |        4 |
    | f    |     6 | true   |        4 |
    +------+-------+--------+----------+
    

    【讨论】:

      猜你喜欢
      • 2022-01-07
      • 2018-06-03
      • 2011-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多