Как выяснить МАКС и МИН групп, которые были добавлены вместе - PullRequest
0 голосов
/ 30 сентября 2018

Как получить МАКСИМАЛЬНОЕ значение столбца, который был сгруппирован и суммирован с помощью _id.

Примерно так:

enter image description here

Затем я хочу отобразить значение MAX для четырех групп, а также значение MINзначение четырех групп.

Примерно так: Scratch High = 702 / Scratch Low = 325

Возможно ли это со встроенными математическими функциями SQLite или мне нужно написать специальный код длявыполнить это?Фактическое число групп будет больше 4, это будет зависеть от того, как часто боулер на самом деле готовит серию.

Пока я не написал никакого кода для этого, я пытаюсь выяснить,это даже возможно, прежде чем пытаться сделать это.Любые предложения будут приветствоваться.Моя попытка интегрироваться в мой проект:

DatabaseHelper.java

public static final String DERIVEDCOL_MAXSCORE = "max_score";
    public static final String DERIVEDCOl_MINSCORE = "min_score";

    public Cursor getMaxMinScoresAllAndroid() {

            SQLiteDatabase db = this.getWritableDatabase();

            String tmptbl = "summed_scores";
            String tmptblcol = "sum_score";

            String crttmptbl = "CREATE TEMP TABLE IF NOT EXISTS " + tmptbl + "(" +
                    tmptblcol + " INTEGER" +
                    ")";
            String empttmptbl = "DELETE FROM " + tmptbl;

            db.execSQL(crttmptbl);
            db.execSQL(empttmptbl);
            String[] columns = new String[]{"sum(score) AS " + tmptblcol};
            Cursor csr = db.query(Game.TABLE_NAME,columns,null,null,Game.COLUMN_BOWLER_ID,null,null);
            DatabaseUtils.dumpCursor(csr);
            while (csr.moveToNext()) {
                ContentValues cv = new ContentValues();
                cv.put(tmptblcol,csr.getInt(csr.getColumnIndex(tmptblcol)));
                db.insert(tmptbl,null,cv);
            }
            csr.close();

            columns = new String[]{"max(" +
                    tmptblcol +
                    ") AS " + DERIVEDCOL_MAXSCORE,
                    "min(" +
                            tmptblcol +
                            ") AS " + DERIVEDCOl_MINSCORE};
            return csr = db.query(tmptbl,columns,null,null,null,null,null);
        }

        public MaxMin getMaxAndminScoresAll() {
            MaxMin rv = new MaxMin(0,0);
            Cursor csr = getMaxMinScoresAllAndroid();
            if (csr.moveToFirst()) {
                rv.setMin(csr.getInt(csr.getColumnIndex(DERIVEDCOl_MINSCORE)));
                rv.setMax(csr.getInt(csr.getColumnIndex(DERIVEDCOL_MAXSCORE)));
            }
            csr.close();
            return rv;
        }

BowlerProfileViewActivity.java

public class BowlerProfileViewActivity extends AppCompatActivity {

    Bowler bowler;

    private DatabaseHelper db;

    private static final String PREFS_NAME = "prefs";
    private static final String PREF_BLUE_THEME = "blue_theme";
    private static final String PREF_GREEN_THEME = "green_theme";
    private static final String PREF_ORANGE_THEME = "purple_theme";
    private static final String PREF_RED_THEME = "red_theme";
    private static final String PREF_YELLOW_THEME = "yellow_theme";

    @Override
    protected void onResume() {
        super.onResume();
        db = new DatabaseHelper(this);
        //mAdapter.notifyDatasetChanged(db.getAllLeagues());
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        //Use Chosen Theme
        SharedPreferences preferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        boolean useBlueTheme = preferences.getBoolean(PREF_BLUE_THEME, false);
        if (useBlueTheme) {
            setTheme(R.style.AppTheme_Blue_NoActionBar);
        }
        boolean useGreenTheme = preferences.getBoolean(PREF_GREEN_THEME, false);
        if (useGreenTheme) {
            setTheme(R.style.AppTheme_Green_NoActionBar);
        }
        boolean useOrangeTheme = preferences.getBoolean(PREF_ORANGE_THEME, false);
        if (useOrangeTheme) {
            setTheme(R.style.AppTheme_Orange_NoActionBar);
        }
        boolean useRedTheme = preferences.getBoolean(PREF_RED_THEME, false);
        if (useRedTheme) {
            setTheme(R.style.AppTheme_Red_NoActionBar);
        }
        boolean useYellowTheme = preferences.getBoolean(PREF_YELLOW_THEME, false);
        if (useYellowTheme) {
            setTheme(R.style.AppTheme_Yellow_NoActionBar);
        }

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bowler_profile_view);

        Intent intent = getIntent();
        Boolean shouldUpdate = getIntent().getExtras().getBoolean("shouldUpdate");
        String savedLeagueId = intent.getStringExtra("leagueId");
        String savedBowlerId = String.valueOf(getIntent().getIntExtra("bowlerId",2));
        int bowlerId = Integer.valueOf(savedBowlerId);

        getBowlerProfile(savedLeagueId, bowlerId);

        // Get The min and max score
        MaxMin bowlerMaxMin =  db.getMaxAndminScoresAll();
        Log.d("SCORES",
                "\n\tMaximum Score is " + String.valueOf(bowlerMaxMin.getMax()) +
                        "\n\tMinimum Score is " + String.valueOf(bowlerMaxMin.getMin()));

    }

    public void getBowlerProfile(String savedLeagueId, int savedBowlerId) {

        String bn, ba, bh;

        SQLiteOpenHelper database = new DatabaseHelper(this);
        SQLiteDatabase db = database.getReadableDatabase();

        Cursor viewBowlerProfile = db.query( Bowler.TABLE_NAME,
                new String[]{Bowler.COLUMN_ID, Bowler.COLUMN_LEAGUE_ID, Bowler.COLUMN_NAME, Bowler.COLUMN_BOWLER_AVERAGE, Bowler.COLUMN_BOWLER_HANDICAP, Bowler.COLUMN_TIMESTAMP},
                Bowler.COLUMN_ID + "=?",
                new String[]{String.valueOf(savedBowlerId)}, null, null, null, null);

        if (viewBowlerProfile.moveToFirst()) {

            //Prepare League Object
            bowler = new Bowler(
                    viewBowlerProfile.getInt(viewBowlerProfile.getColumnIndex(Bowler.COLUMN_ID)),
                    viewBowlerProfile.getString(viewBowlerProfile.getColumnIndex(Bowler.COLUMN_LEAGUE_ID)),
                    bn = viewBowlerProfile.getString(viewBowlerProfile.getColumnIndex(Bowler.COLUMN_NAME)),
                    ba = viewBowlerProfile.getString(viewBowlerProfile.getColumnIndex(Bowler.COLUMN_BOWLER_AVERAGE)),
                    bh = viewBowlerProfile.getString(viewBowlerProfile.getColumnIndex(Bowler.COLUMN_BOWLER_HANDICAP)),
                    viewBowlerProfile.getString(viewBowlerProfile.getColumnIndex(Bowler.COLUMN_TIMESTAMP)));

            final TextView bowlerName = (TextView) findViewById(R.id.tvBowlerName);
            final TextView bowlerAverage = (TextView) findViewById(R.id.tvBowlerAverageValue);
            final TextView bowlerHandicap = (TextView) findViewById(R.id.tvBowlerHandicapValue);

            bowlerName.setText(String.valueOf(bn));
            bowlerAverage.setText(String.valueOf(ba));
            bowlerHandicap.setText(String.valueOf(bh));

            //Close Database Connection
            viewBowlerProfile.close();
        }

        //View League Profile Cancel Button
        final Button cancel_button = (Button) findViewById(R.id.bCancel);
        cancel_button.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                Log.d("SAVEDLEAGUEID_VAL", ">>" + String.valueOf(savedLeagueId) + "<<");
                Intent intent = new Intent(getApplicationContext(), BowlerActivity.class);
                intent.putExtra("leagueId", savedLeagueId);
                startActivity(intent);
                finish();
                overridePendingTransition(0, 0);
                /*Intent intent = new Intent(getApplicationContext(), BowlerActivity.class);
                intent.putExtra("leagueId", savedLeagueId);
                Log.d("LEAGUEID VALUE","value of leagueId = " + String.valueOf(savedLeagueId));
                startActivity(intent);
                finish();
                overridePendingTransition(0, 0);*/
            }

        });

        //Edit League Profile Cancel Button
        final Button edit_button = (Button) findViewById(R.id.bEdit);
        edit_button.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                int bowlerId = bowler.getId();
                Intent intent = new Intent(getApplicationContext(), BowlerProfileEditActivity.class);
                intent.putExtra("bowlerId", bowlerId);
                intent.putExtra("leagueId", savedLeagueId);
                startActivity(intent);
                finish();
                overridePendingTransition(0, 0);
            }

        });
    }
}

Logcat

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'ca.rvogl.tpbcui.utils.MaxMin ca.rvogl.tpbcui.database.DatabaseHelper.getMaxAndminScoresAll()' on a null object reference
        at ca.rvogl.tpbcui.views.BowlerProfileViewActivity.onCreate(BowlerProfileViewActivity.java:79)
        at android.app.Activity.performCreate(Activity.java:6679)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)

Попыткагруппировка по bowlerId и seriesId

public Cursor getMaxMinScoresAllAndroid(String bowlerId) {

    SQLiteDatabase db = this.getWritableDatabase();

    String tmptbl = "summed_scores";
    String tmptblcol = "sum_score";
    String tmpBowlerIdCol = "bowler_id";
    String tmpSeriesIdCol = "series_id";

    String crttmptbl = "CREATE TEMP TABLE IF NOT EXISTS " + tmptbl + "(" +
            tmptblcol + " INTEGER," + 
            tmpBowlerIdCol + " TEXT," + 
            tmpSeriesIdCol + " TEXT)";
    String empttmptbl = "DELETE FROM " + tmptbl;

    db.execSQL(crttmptbl);
    db.execSQL(empttmptbl);
    String[] columns = new String[]{"sum(score) AS "};
    Cursor csr = db.query(Game.TABLE_NAME,columns,null,null,Game.COLUMN_BOWLER_ID + " = '" + bowlerId + "'", Game.COLUMN_SERIES_ID,null,null);
    DatabaseUtils.dumpCursor(csr);
    while (csr.moveToNext()) {
        ContentValues cv = new ContentValues();
        cv.put(tmptblcol,csr.getInt(csr.getColumnIndex(tmptblcol)));
        cv.put(tmpBowlerIdCol,csr.getInt(csr.getColumnIndex(tmpBowlerIdCol)));
        cv.put(tmpSeriesIdCol,csr.getInt(csr.getColumnIndex(tmpSeriesIdCol)));
        db.insert(tmptbl,null,cv);
    }
    csr.close();

    columns = new String[]{"max(" +
            tmptblcol +
            ") AS " + DERIVEDCOL_MAXSCORE,
            "min(" +
                    tmptblcol +
                    ") AS " + DERIVEDCOl_MINSCORE};
    return csr = db.query(tmptbl,columns,null,null,null,null,null);
}

public MaxMin getMaxAndminScoresAll(String bowlerId) {
    MaxMin rv = new MaxMin(0,0);
    Cursor csr = getMaxMinScoresAllAndroid(bowlerId);
    if (csr.moveToFirst()) {
        rv.setMin(csr.getInt(csr.getColumnIndex(DERIVEDCOl_MINSCORE)));
        rv.setMax(csr.getInt(csr.getColumnIndex(DERIVEDCOL_MAXSCORE)));
    }
    csr.close();
    return rv;
}

1 Ответ

0 голосов
/ 30 сентября 2018

Вы можете сделать это (при условии, что таблица имеет имя myscores и столбцы _id и score ), используя: -

WITH cte1 AS 
    (
        sum(score) AS sum_score
        FROM myscores
        GROUP BY _id
    )
SELECT max(sum_score) AS min_score, min(sum_score) FROM cte1;

Использование этого приведет к следующему: -

enter image description here

  • Примечания
  • AS используется для переименования выходных столбцов

При этом используются агрегатные функции SQLite max и min и предложение GROUP BY для агрегирования столбцов в соответствии со столбцом _id.

При этом также используется выражение общей таблицы (промежуточная / временная таблица). SQL как понял SQLite - предложение WITH


Включение в приложение Android (см. Примечание в конце)

Ниже приведен пример приложения, демонстрирующий, как это можетбыть встроенным для Android: -

Сначала простой класс для минимального и максимального значений (как используется в альтернативном методе getMaxAndMinScores)

MaxMin.java (необязательно)

public class MaxMin {

    private int min;
    private int max;

    public MaxMin(int min, int max) {
        this.min = min;
        this.max = max;
    }

    public int getMin() {
        return min;
    }

    public void setMin(int min) {
        this.min = min;
    }

    public int getMax() {
        return max;
    }

    public void setMax(int max) {
        this.max = max;
    }
}

DBHelper.java

Подкласс SQLiteOpenHelper (только одно имя таблицы myscores)

public class DBHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb";
    public static final int DBVERSION = 1;
    public static final String TB_SCORE = "myscores";
    public static final String COL_SCORE = "score";
    public static final String COL_ID = BaseColumns._ID;

    public static final String DERIVEDCOL_MAXSCORE = "max_score";
    public static final String DERIVEDCOl_MINSCORE = "min_score";

    private static final String crt_myscores_sql = "CREATE TABLE IF NOT EXISTS " + TB_SCORE + "(" +
            COL_ID + " INTEGER," +
            COL_SCORE + " INTEGER" +
            ")";

    public DBHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(crt_myscores_sql);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int i, int i1) {

    }

    public long addScore(long id, int score) {
        ContentValues cv = new ContentValues();
        cv.put(COL_ID,id);
        cv.put(COL_SCORE,score);
        return this.getWritableDatabase().insert(TB_SCORE,null,cv);
    }

    public Cursor getMaxMinScores() {
        String sum_score = "sum_score";
        String cte1 = "cte1";
        String rawqry = " WITH " + cte1 +
                " AS " +
                "(" +
                "SELECT sum(" +
                COL_SCORE +
                ") AS " + sum_score +
                " FROM " + TB_SCORE + " GROUP BY " + COL_ID +
                ") " +
                "SELECT " +
                " max(" +
                sum_score +
                ") AS " + DERIVEDCOL_MAXSCORE +
                "," +
                " min(" +
                sum_score +
                ") AS " + DERIVEDCOl_MINSCORE +
                " FROM " + cte1 + ";";
        return this.getWritableDatabase().rawQuery(rawqry,null);
    }

    public MaxMin getMaxAndMinScores() {
        MaxMin rv = new MaxMin(0,0);
        Cursor csr = getMaxMinScores();
        if (csr.moveToFirst()) {
            rv.setMin(csr.getInt(csr.getColumnIndex(DERIVEDCOl_MINSCORE)));
            rv.setMax(csr.getInt(csr.getColumnIndex(DERIVEDCOL_MAXSCORE)));
        }
        csr.close();
        return rv;
    }
}

MainActivity.java

Операция, которая а) добавляет несколько строк изатем b) получает максимальные и минимальные оценки (дважды, используя альтернативные методы): -

public class MainActivity extends AppCompatActivity {

    DBHelper mDBHlpr;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDBHlpr = new DBHelper(this);
        // Add Some scores
        mDBHlpr.addScore(1,112);
        mDBHlpr.addScore(1,123);
        mDBHlpr.addScore(1,144);
        mDBHlpr.addScore(2,212);
        mDBHlpr.addScore(2,190);
        mDBHlpr.addScore(2,300);
        mDBHlpr.addScore(3,234);
        mDBHlpr.addScore(3,134);
        mDBHlpr.addScore(3,122);
        mDBHlpr.addScore(4,100);
        mDBHlpr.addScore(4,111);
        mDBHlpr.addScore(4,114);

        // Get The min and max scores example 1
        Cursor csr = mDBHlpr.getMaxMinScores();
        if (csr.moveToFirst()) {
            int max_score = csr.getInt(csr.getColumnIndex(DBHelper.DERIVEDCOL_MAXSCORE));
            int min_score = csr.getInt(csr.getColumnIndex(DBHelper.DERIVEDCOl_MINSCORE));
            Log.d("SCORES",
                    "\n\tMaximum Score is " + String.valueOf(max_score) +
                            "\n\tMinimum Score is " + String.valueOf(min_score)
            );
        }

        //Alternative utilising the MaxMin object
        MaxMin mymaxmin =  mDBHlpr.getMaxAndMinScores();
        Log.d("SCORES",
                "\n\tMaximum Score is " + String.valueOf(mymaxmin.getMax()) +
                        "\n\tMinimum Score is " + String.valueOf(mymaxmin.getMin())
        );
    }
}

ВАЖНО

Предложение WITH было введено в SQL 3.8.3, некоторые более старые версии Android (ниже lollipop (но могут быть независимыми от устройства)) не будут поддерживать предложение WITH.

Следующие методы, как эквиваленты getMaxMinScores иgetMaxAndMinScores можно использовать для любой Androidrsion: -

public Cursor getMaxMinScoresAllAndroid() {

    SQLiteDatabase db = this.getWritableDatabase();

    String tmptbl = "summed_scores";
    String tmptblcol = "sum_score";

    String crttmptbl = "CREATE TEMP TABLE IF NOT EXISTS " + tmptbl + "(" +
            tmptblcol + " INTEGER" +
            ")";
    String empttmptbl = "DELETE FROM " + tmptbl;

    db.execSQL(crttmptbl);
    db.execSQL(empttmptbl);
    String[] columns = new String[]{"sum(score) AS " + tmptblcol};
    Cursor csr = db.query(TB_SCORE,columns,null,null,COL_ID,null,null);
    DatabaseUtils.dumpCursor(csr);
    while (csr.moveToNext()) {
        ContentValues cv = new ContentValues();
        cv.put(tmptblcol,csr.getInt(csr.getColumnIndex(tmptblcol)));
        db.insert(tmptbl,null,cv);
    }
    csr.close();

    columns = new String[]{"max(" +
            tmptblcol +
            ") AS " + DERIVEDCOL_MAXSCORE,
            "min(" +
                    tmptblcol +
                    ") AS " + DERIVEDCOl_MINSCORE};
    return csr = db.query(tmptbl,columns,null,null,null,null,null);
}

public MaxMin getMaxAndminScoresAllAndroid() {
    MaxMin rv = new MaxMin(0,0);
    Cursor csr = getMaxMinScoresAllAndroid();
    if (csr.moveToFirst()) {
        rv.setMin(csr.getInt(csr.getColumnIndex(DERIVEDCOl_MINSCORE)));
        rv.setMax(csr.getInt(csr.getColumnIndex(DERIVEDCOL_MAXSCORE)));
    }
    csr.close();
    return rv;
}
  • Они используют промежуточную временную таблицу, так что обойти ограничение использования WITH
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...