繁体   English   中英

根据上一个和下一个字段的值计算字段值

Calculating a fields value according to the values of the previous and next fields

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

为了清楚起见,假设我有一个带有carID,里程和日期的表。 日期始终为月(例如2015年2月1日,2015年3月1日等)。 每个carID每月都有一行,但并非每一行都有Mileage字段的值,有些则为NULL。

表格示例:

carID           mileage           date
-----------------------------------------
1               400            01/01/2015
2               NULL           01/02/2015
3               NULL           01/03/2015
4               1050           01/04/2015

如果此类字段为NULL,则需要通过查看上一个和下一个值来计算其应具有的值(这些值不一定是下个月或上个月,它们可以相隔数月)。

我想通过取上一个和下一个值的差值来执行此操作,然后计算它们之间的时间,并使该值与时间相对应。 但是我不知道该怎么做。

我之前已经使用了一些代码来查看下一个值,如下所示:

, carKMcombiDiffList as (
select ml.*,
       (ml.KM - mlprev.KM) as diff
from carKMcombilist ml outer apply
     (select top 1 ml2.*
      from carKMcombilist ml2
      where ml2.FK_CarID = ml.FK_CarID and
            ml2.beginmonth < ml.beginmonth
      order by ml2.beginmonth desc
     ) mlprev
)

这是在检查当前值是否大于先前值。 我想我也可以用它来检查当前问题中的上一个,我只是不知道如何在其中添加下一个以及进行计算所需的所有逻辑。

2 个回复

以下查询获取记录的上一个和下一个可用里程。

with data as --test data
(
    select * from (VALUES
        (0, null, getdate()),
        (1, 400, '20150101'),
        (1, null, '20150201'),
        (1, null, '20150301'),
        (1, 1050, '20150401'),
        (2, 300, '20150101'),
        (2, null, '20150201'),
        (2, null, '20150301'),
        (2, 1235, '20150401'),
        (2, null, '20150501'),
        (2, 1450, '20150601'),
        (3, 200, '20150101'),
        (3, null, '20150201')
    ) as v(carId, mileage, [date])
    where v.carId != 0
)
-- replace 'data' with your table name
select  d.*, 
        (select top 1 mileage from data dprev where dprev.mileage is not null and dprev.carId = d.carId and dprev.[date] <= d.date order by dprev.[date] desc) as 'Prev available mileage',
        (select top 1 mileage from data dnext where dnext.mileage is not null and dnext.carId = d.carId and dnext.[date] >= d.date order by dnext.[date] asc) as 'Next available mileage'
from    data d

请注意,如果在特定日期之前/之后没有可用数据,则这些列仍可以为null

从这里开始,您将如何使用这些值。 可能您想插入缺少mileage记录的值。

编辑

为了对缺失的里程值进行插值,我必须计算三个辅助列:

ri缺少里程的连续组中的记录索引
gi每辆车缺少里程的连续组的索引
gc缺少里程的每个连续组的记录数

上面查询中的限制列已重命名为
pa (以前可用)和
na (下一个可用)。

该查询不是紧凑的,我敢肯定它可以改进,但是级联CTE的优点在于您可以轻松地检查中间结果并了解每个步骤。

SQL小提琴: SO 29363187

with data as --test data
(
    select * from (VALUES
        (0, null, getdate()),
        (1, 400, '20150101'),
        (1, null, '20150201'),
        (1, null, '20150301'),
        (1, 1050, '20150401'),
        (2, 300, '20150101'),
        (2, null, '20150201'),
        (2, null, '20150301'),
        (2, 1235, '20150401'),
        (2, null, '20150501'),
        (2, 1450, '20150601'),
        (3, 200, '20150101'),
        (3, null, '20150201')
    ) as v(carId, mileage, [date])
    where v.carId != 0
),
-- replace 'data' with your table name
limits AS
(
    select  d.*, 
            (select top 1 mileage from data dprev where dprev.mileage is not null and dprev.carId = d.carId and dprev.[date] <= d.date order by dprev.[date] desc) as pa,
            (select top 1 mileage from data dnext where dnext.mileage is not null and dnext.carId = d.carId and dnext.[date] >= d.date order by dnext.[date] asc) as na
    from    data d
),
t1 as
(
    SELECT l.*,
           case when mileage is not null 
                then null 
                else row_number() over (partition by l.carId, l.pa, l.na  order by  l.carId, l.[date])
           end as ri,   -- index of record in a continuous group where mileage is missing
           case when mileage is not null 
                then null 
                else dense_rank() over (partition by carId order by  l.carId, l.pa, l.na)
           end as gi    -- index of  a continuous group where mileage is missing per car
    from limits l
),
t2 as
(
    select  *,
            (select count(*) from t1 tm where tm.carId = t.carId and tm.gi = t.gi)  gc  --count of records per continuous group where mileage is missing
    FROM    t1 t
)
select  *,
        case when mileage is NULL
            then pa + (na - pa) / (gc + 1.0) * ri   -- also converts from integer to decimal
            else NULL
        end as 'Interpolated value' 
from    t2
order by carId, [date]

假设:CarID和日期始终是唯一的组合

这是我想出的:

select with_dates.*,
       prev_mileage.mileage as prev_mileage,
       next_mileage.mileage as next_mileage,
       next_mileage.mileage - prev_mileage.mileage as mileage_delta,
       datediff(month,prev_d,next_d) as month_delta,
       (next_mileage.mileage - prev_mileage.mileage)/datediff(month,prev_d,next_d)*datediff(month,prev_d,with_dates.d) + prev_mileage.mileage as estimated_mileage
  from (select *,
          (select top 1 d
             from mileage as prev
            where carid = c.carid
              and prev.d < c.d
              and prev.mileage is not null
         order by d desc ) as prev_d,
           (select top 1 d
             from mileage as next_rec
            where carid = c.carid
              and next_rec.d > c.d
              and next_rec.mileage is not null
         order by d asc) as next_d
          from mileage as c
         where mileage is null) as with_dates
  join mileage as prev_mileage
    on     prev_mileage.carid = with_dates.carid
       and prev_mileage.d = with_dates.prev_d
  join mileage as next_mileage
    on     next_mileage.carid = with_dates.carid
       and next_mileage.d = with_dates.next_d

逻辑:首先,对于每一个mileage is null记录我选择了一个和下一个日期,其中mileage is not null 在此之后,我只是根据龋齿和日期加入行,并做一些简单的数学运算即可近似。

希望这会有所帮助,这很有趣。

1 使用MySQL中的上一个值来计算下一个字段?

如何在MySQL中使用上一个值来计算下一个值? 我无法用较差的英语来解释我的意思(任何人都可以通过查看此帖子的标题来理解我的要求吗?),所以让我在摘要中进行解释: 在上面的代码段中,当您运行查询时,您会收到错误消息,因为events表中没有诸如h或ab这样的列。 但是,我想使用在以前 ...

2013-10-30 15:15:18 3 124   mysql/ sql
2 根据下一个字段中的值选择或不选择一个字段

从这样的表中(仅在这里): 我该如何选择: 这些是不正确的。 我把它们包括在内是为了让您有个好主意。 实际上,仅当_s的值为0时才需要数据。 可以使用sql完成此操作,还是必须使用php实现? ...

3 HTML表单,在完成上一个字段后生成下一个字段

我正在寻找创建一个表单,只有在正确完成上一部分后才能显示下一部分。 我如何利用后退和下一个按钮来执行此操作? 如果我按下它,它将改变显示设置,但理论上会使前一部分不可编辑。 如果我按下后退按钮,它是否会重新创建上一部分,从而消除所有条目? 作为参考,我试图制作这种buzzfeed测验 ...

4 如何在SQL Server中添加上一个字段和下一个字段?

我有三个表: “记录”表具有一个称为“ date_record”的日期字段,“客户”表的外键以及“奖励”表的外键及其各自的主键 “奖励”表具有三个字段:其主键,存储称为“ reward_value”的整数值的列以及说明 “客户”表具有两个字段:它的主键和客户的 名称 ...

6 javascript更新下一个/上一个输入字段值

我有一个表格,每条记录都有一个输入字段,其两侧有一个减号和加号按钮。 我试图得到它,以便当用户单击加号按钮时,它会将输入字段的值增加一,反之亦然。 我为 JavaScript 生成我的表记录: + "&lt;td class=\"text-center\"&gt;" + "&lt;sp ...

7 jQuery Mobile Header Android下一个字段

所以,我在这里沮丧地在Android浏览器上挠头! Android版本2.3.6。 这东西怎么了? 下一个和之前(也许是上一个)按钮不起作用! ...在一些基本的jquery表单字段上。 具有: 但是...如果我删除data-role =“ header”,那该死的东西就开 ...

8 当字段值达到最大长度时,如何关注下一个字段

我有一个场景,我有两个或更多textarea,当用户输入textarea中的值,当值达到max-length,例如ng-max-length为15时,焦点应自动移动到下一个文本区域。 如何实现这一目标? 为了控制最大长度,我从这个链接中获得了解决方案。 但我不知道如何自动关注下 ...

9 读取 Elementor 表单字段的值,并将其用于下一个字段

我想在 Wordpress 的 Elementor Pro 表单中创建一个级联下拉列表。 我想读取用户在较早的下拉列表中选择的值,然后使用它来自定义填充第二个选择下拉列表。 例如,如果用户在国家/地区选择法国,我们在第二个下拉列表中显示法国城市,如果用户在国家/地区选择德国,我们将显示德国城市。 ...

10 如果缺少字段值并且用户开始为下一个字段键入内容,如何显示错误消息?

例如-如果用户开始输入密码但尚未输入电子邮件,但立即显示消息-“首先输入电子邮件ID”。 我正在使用bootstrap4&jQuery / Javascript。光标应该到达发现错误的字段,并且在满足所有验证条件的情况下,当我单击Submit按钮时如何重定向到另一个页面。 我曾尝试在HTML ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM