SQL Server - 根据columndata从X个月前获取值

时间:2018-05-18 07:49:18

标签: sql-server

假设我有下表(数据完全是虚构的):

ID | MonthDate | PersonID | Name | Status  | MonthsAgoSinceLastCheck
1  | 2017-12   | 900      | Jack | Ill     | -
2  | 2018-01   | 900      | Jack | Ill     | 1
3  | 2018-02   | 900      | Jack | Ill     | 2
4  | 2018-03   | 900      | Jack | Healthy | 1
5  | 2017-02   | 901      | Bill | Ill     | -
6  | 2017-03   | 901      | Bill | Ill     | 1
7  | 2017-05   | 901      | Bill | Healthy | 1

对于每条记录,我希望看到自上次检查以来该人在X个月前的状态(列MonthsAgoSinceLastCheck)。请注意,MonthDate可以跳过几个月。

所以在这种情况下,结果将是

ID | MonthDate | PersonID | Name | Status  | MonthsAgoSinceLastCheck | PreviousSatus
1  | 2017-12   | 900      | Jack | Ill     | -                       | -
2  | 2018-01   | 900      | Jack | Ill     | 1                       | Ill
3  | 2018-02   | 900      | Jack | Ill     | 2                       | Ill
4  | 2018-03   | 900      | Jack | Healthy | 1                       | Ill
5  | 2017-02   | 901      | Bill | Healthy | -                       | -
6  | 2017-03   | 901      | Bill | Healthy | 1                       | Healthy 
7  | 2017-05   | 901      | Bill | Ill     | 2                       | Healthy 

任何sugestions /提示?我尝试用CTE和自连接来做这个,但两者都失败了。

2 个答案:

答案 0 :(得分:0)

使用完整日期比分别使用年份和月份更容易。你应该做的第一件事是从你的年份+月生成一个完整的日期。然后根据最后一次检查,自己加入上个月。

;WITH DataWithDates AS
(
    SELECT
        T.ID,
        MonthDate = CONVERT(DATE, T.MonthDate + '-01'),
        T.PersonID,
        T.Name,
        T.Status,
        T.MonthsAgoSinceLastCheck
    FROM
        YourTable AS T
)
SELECT
    D.ID,
    D.MonthDate,
    D.PersonID,
    D.Name,
    D.Status,
    D.MonthsAgoSinceLastCheck,
    PreviousStatus = N.Status
FROM
    DataWithDates AS D
    LEFT JOIN DataWithDates AS N ON
        D.PersonID = N.PersonID AND
        N.MonthDate = DATEADD(MONTH, -1 * D.MonthsAgoSinceLastCheck, D.MonthDate)

我假设您的MonthDate包含所有行的值,否则转换将失败。我还假设-的{​​{1}}值实际上是MonthsAgoSinceLastCheck

答案 1 :(得分:0)

试试这个:

  public class FingerprintHandler extends 
   FingerprintManager.AuthenticationCallback {
    private CancellationSignal cancellationSignal;
    private Context appContext;

    public FingerprintHandler(Context context) {
      appContext = context;
  }

public void startAuth(FingerprintManager manager,
                      FingerprintManager.CryptoObject cryptoObject) {

    cancellationSignal = new CancellationSignal();

    if (ActivityCompat.checkSelfPermission(appContext,
            Manifest.permission.USE_FINGERPRINT) !=
            PackageManager.PERMISSION_GRANTED) {
        return;
    }
    manager.authenticate(cryptoObject, cancellationSignal, 0, this, null);

}

@Override
public void onAuthenticationError(int errMsgId,
                                  CharSequence errString) {
    scannerDialog(errString.toString());
}

public void scannerDialog(String message) {
    Toast.makeText(appContext, message, Toast.LENGTH_LONG).show();
}

@Override
public void onAuthenticationHelp(int helpMsgId,
                                 CharSequence helpString) {
    scannerDialog("" + helpString);
}

@Override
public void onAuthenticationFailed() {
    scannerDialog("Access denied");
}

@Override
public void onAuthenticationSucceeded(
        FingerprintManager.AuthenticationResult result) {
    Log.e("LoginSuccess","Success");
    //After it was verified, I want to get the Fingerprint name of the verified fingerprint


}
}

SQl小提琴:http://sqlfiddle.com/#!18/04407/4