具有条件的列上的MySQL Rowsum

时间:2018-01-03 14:17:53

标签: mysql sql

我有下表

OR

此表记录在特定时间范围内发生的事件数。也就是说,在给定的时间范围(0-4,4-8,8-12,12-16,16-20,20-24点),来自特定用户ID的网站页面浏览量。 / p>

我想用SQL计算以下内容:
有多少个时间帧(每个用户),至少有一次访问?
有多少个时间帧(每个用户),至少有k次访问(k = 5,10)?

期望的结果:

+--------+----+----+----+----+----+----+
| userid | z0 | z1 | z2 | z3 | z4 | z5 |
+--------+----+----+----+----+----+----+
| 4711   |  0 |  1 |  1 |  0 |  0 |  0 |
| 4712   |  1 |  1 |  8 |  0 |  5 |  0 |
| 4713   |  3 |  5 |  1 |  0 |  0 |  0 |
| 4714   |  0 |  4 |  2 |  0 | 11 |  0 |
+--------+----+----+----+----+----+----+

到目前为止我所拥有的:
对于这个问题:“有多少个时间帧(每个用户),至少有一次访问?”我尝试过类似的东西,但这不起作用:

+--------+--------+--------+---------+
| userid | visit1 | visit5 | visit10 |
+--------+--------+--------+---------+
| 4711   |     2  |      0 |       0 |
| 4712   |     4  |      2 |       0 |
| 4713   |     3  |      1 |       0 |
| 4714   |     3  |      1 |       1 |
+--------+--------+--------+---------+

3 个答案:

答案 0 :(得分:0)

修复架构后,有效查询可能如下所示:

SELECT userid
     , SUM(k>=1)  visit1
     , SUM(k>=5)  visit5
     , SUM(k>=10) visit10 
  FROM my_table 
 GROUP 
    BY userid;

答案 1 :(得分:0)

正如草莓所提到的,最好修改你的架构设计。但是,如果您只想获得所需的结果,可以试试这个(不是最佳解决方案):

SELECT  userid,
    z0 + z1 + z2 + z3 + z4 + z5 as visit1,
    z0_5 + z1_5 + z2_5 + z3_5 + z4_5 + z5_5 as visit5,
    z0_10 + z1_10 + z2_10 + z3_10 + z4_10 + z5_10 as visit10

FROM (
   SELECT 
   userid,

   CASE WHEN z0>0 THEN 1 ELSE 0 END z0,
   CASE WHEN z1>0 THEN 1 ELSE 0 END z1,
   CASE WHEN z2>0 THEN 1 ELSE 0 END z2,
   CASE WHEN z3>0 THEN 1 ELSE 0 END z3,
   CASE WHEN z4>0 THEN 1 ELSE 0 END z4,
   CASE WHEN z5>0 THEN 1 ELSE 0 END z5,

   CASE WHEN z0>4 THEN 1 ELSE 0 END z0_5,
   CASE WHEN z1>4 THEN 1 ELSE 0 END z1_5,
   CASE WHEN z2>4 THEN 1 ELSE 0 END z2_5,
   CASE WHEN z3>4 THEN 1 ELSE 0 END z3_5,
   CASE WHEN z4>4 THEN 1 ELSE 0 END z4_5,
   CASE WHEN z5>4 THEN 1 ELSE 0 END z5_5,

   CASE WHEN z0>9 THEN 1 ELSE 0 END z0_10,
   CASE WHEN z1>9 THEN 1 ELSE 0 END z1_10,
   CASE WHEN z2>9 THEN 1 ELSE 0 END z2_10,
   CASE WHEN z3>9 THEN 1 ELSE 0 END z3_10,
   CASE WHEN z4>9 THEN 1 ELSE 0 END z4_10,
   CASE WHEN z5>9 THEN 1 ELSE 0 END z5_10

   FROM timetable 
   GROUP BY userid
) as test

DEMO

答案 2 :(得分:0)

根据您现有的结构,如果你可以调整到更好的格式会让事情变得更容易......但是不能忍受,试试

public class MyDrawView extends View {

private Bitmap  mBitmap;
private Canvas  mCanvas;
private Path    mPath;
private Paint   mBitmapPaint;
private Paint   mPaint;

public MyDrawView(Context c) {
    super(c);

    mPath = new Path();
    mBitmapPaint = new Paint(Paint.DITHER_FLAG);

    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(0xFF000000);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(3);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    mCanvas = new Canvas(mBitmap);
}

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

    canvas.drawPath(mPath, mPaint);
}

private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;

private void touch_start(float x, float y) {
    mPath.reset();
    mPath.moveTo(x, y);
    mX = x;
    mY = y;
}
private void touch_move(float x, float y) {
    float dx = Math.abs(x - mX);
    float dy = Math.abs(y - mY);
    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
        mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
        mX = x;
        mY =  y;
    }
}
private void touch_up() {
    mPath.lineTo(mX, mY);
    // commit the path to our offscreen
    mCanvas.drawPath(mPath, mPaint);
    // kill this so we don't double draw
    mPath.reset();
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            touch_start(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_MOVE:
            touch_move(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            touch_up();
            invalidate();
            break;
    }
    return true;
}

public void clear(){
    mBitmap.eraseColor(Color.TRANSPARENT);
    invalidate();
    System.gc();
}
}