使用SQL(对于MySQL),如何根据前一行的数据更新行上的数据?

时间:2015-04-23 22:12:59

标签: mysql sql

我在scott列中有这些产品SKU是字母数字(应始终包含数字但不总是字母)。 id列会自动递增。所有数据都是从CSV文件逐行导入的,所以我知道数据的顺序是正确的。

从这张图片中可以看出,一些scott字段只是字母,前面应该有前面的数字。例如,在id 5149上,我希望scott为3780a。

enter image description here

所以问题是这样的:使用SQL,我如何按顺序解析行,将scott号码从包含数字的最新字段添加到以下字段中它不包含数字?

3 个答案:

答案 0 :(得分:3)

这是一个使用用户定义变量来确定最近的前一个数值的选项。

update yourtable y
join (
  select id, scott, @prevNumericId:=
          if(scott REGEXP '^[0-9]+$', scott, @prevNumericId) prevNumericId
  from yourtable, (select @prevNumericId:=0) t
  order by id   
  ) t on y.id = t.id and y.scott = t.scott
set y.scott = concat(t.prevNumericId,y.scott)
where y.scott not REGEXP '^[0-9]+$'

答案 1 :(得分:0)

public class Tariff implements Parcelable {

private String operator;
private Discounts discount;
private boolean unlimited;
private Billings billing;
private String name;
private double price;
private double calculated;
private Call call;
private Sms sms;

    protected Tariff(Parcel in) {
        operator = in.readString();
        discount = (Discounts) in.readValue(Discounts.class.getClassLoader());
        unlimited = in.readByte() != 0x00;
        billing = (Billings) in.readValue(Billings.class.getClassLoader());
        name = in.readString();
        price = in.readDouble();
        calculated = in.readDouble();
        call = (Call) in.readValue(Call.class.getClassLoader());
        sms = (Sms) in.readValue(Sms.class.getClassLoader());
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(operator);
        dest.writeValue(discount);
        dest.writeByte((byte) (unlimited ? 0x01 : 0x00));
        dest.writeValue(billing);
        dest.writeString(name);
        dest.writeDouble(price);
        dest.writeDouble(calculated);
        dest.writeValue(call);
        dest.writeValue(sms);
    }

    @SuppressWarnings("unused")
    public static final Parcelable.Creator<Tariff> CREATOR = new Parcelable.Creator<Tariff>() {
        @Override
        public Tariff createFromParcel(Parcel in) {
            return new Tariff(in);
        }

        @Override
        public Tariff[] newArray(int size) {
            return new Tariff[size];
        }
    };
}

答案 2 :(得分:0)

那个好老的第一个(或者在这种情况下,最后) - 孩子的问题,但这次是在同一张桌子上..

这应该非常优雅地为您完成工作:

UPDATE mytable dest
JOIN (
SELECT mt.id, CONCAT(lnk.scott, mt.scott) AS newValue
FROM mytable mt

LEFT OUTER JOIN mytable lnk ON lnk.id < mt.id AND CONCAT('',SUBSTRING(lnk.scott, 1, 1) * 1) != 0
LEFT OUTER JOIN mytable lnk2 ON lnk2.id < mt.id AND CONCAT('',SUBSTRING(lnk2.scott, 1, 1) * 1) != 0
    AND lnk.id < lnk2.id

WHERE lnk2.id IS NULL
AND CONCAT('',SUBSTRING(mt.scott, 1, 1) * 1) = 0
) AS source on source.id = dest.id

SET dest.scott = source.newValue

===

我没有足够的代表评论,但@ sgeddes的解决方案基本相同,但使用用户定义的变量。只要变量不在并发执行之间交叉,那应该没问题。)

无论如何,这个版本将很乐意同时运行。