my table look like this:
Client_Code Oder_ID NoOrd Weight
850458 5 1 12
850458 5 2 12
850458 6 1 5
i want to sum the Weight, but unique par Oder_ID.
so the resultat that i want is 17 = 12 + 5
not 29
how can i do that ?
my code like this;
public int GetPoids()
{
String SQL_syntax = "SELECT SUM("+ DBHelper.KEY_Poids +") as SumPoids FROM " + DBHelper.tableName + " GROUP BY " + DBHelper.KEY_CodeClient +","+DBHelper.KEY_NoOrdre ;
Cursor c = database.rawQuery(SQL_syntax, null);
if (c != null)
c.moveToFirst();
int Poids = c.getInt(0);
c.close();
return Poids;
}
Give a try, First you need to get unique OrderIds then take only one record of that OrderId with one more condition NoOrd=1 (it must have atleast NoOrd=1 in each record)
select sum(Weight) from Table_Name where Order_ID in (select distinct Order_ID from Table_Name) and NoOrd=1
Sorry if it doesn't help you, actually I tried on a online tool due to lack of your database structure.
Related
This question already has an answer here:
How to get the row# nearest to current time in SQLite for Android rawQuery
(1 answer)
Closed 6 years ago.
Experts,
Here is my goal:
get the value of A from a query, where B=max(B), if the query return 0 row, then set 999999.
If use Method 1, syntax error because no group by clause, but I don't need a group.
If use Method 2, when CONDITIONS are false, namely 0 row, the cursor.getCount() ==1 >0, cannot get 999999.
One way I can think of is add a column C set value 'constant' in tb, then add group by C in Method 1.
But it is totally not grace.
What should I do? Thanks.
Method 1:
Cursor cursor = db.rawQuery("select A, B " +
"from tb " +
"where "CONDITIONS" +
"having B=max(B)", null);
cursor.moveToFirst();
valueA = cursor.getDouble(0);
if (cursor.getCount()==0) valueA = 999999;
cursor.close();
Method 2:
Cursor cursor = db.rawQuery("select A, max(B) " +
"from tb " +
"where "CONDITIONS", null);
cursor.moveToFirst();
valueA = cursor.getDouble(0);
if (cursor.getCount() == 0) valueA = 999999;
cursor.close();
You should place the 'max(b)' function in the select clause, because this is the best way to find the aggregate.
You will get at least one row in the resulting cursor even if the values are NULL. So, you should read the value of 'max(b)' from the cursor and then add the logic.
In your first method, you are using the keyword having which is used with the GROUP BY keyword. So the code is giving you the error.
Having keyword example:
SELECT * FROM Students GROUP BY name HAVING count(name) < 2;
You can use following command:
SELECT column_name FROM table_name where MAX(column_name);
and:
cursor.moveToFirst();
if (cursor.getCount()<1){
valueA= 999999;
}else{
valueA= cursor.getDouble(0);
}
cursor.close();
If use group function you must use group by .
You can use sub query like this ..
Cursor cursor = db.rawQuery("select A , B " +
"from tb " +
"where "CONDITIONS" +
" AND B = (select max(B) from tb)", null);
I am running a query in sqllite browser which gives the output fine.
But when i am running the query through Android's SqlLiteDatabase's rawQuery function it returns 3 rows for every original row
The query being -
select s.shout_id, u.user_id, u.image_id , u.firstname, u.lastname, s.shout_msg , i.user_id 'r_user_id' , i.image_id 'r_img_id', i.firstname 'r_firstname', i.lastname 'r_lastname', s.rec_time from shouts s left join users u
on s.user_id = u.user_id left join users i on s.reciever_id = i.user_id
where ((s.user_id =1 and s.reciever_id =2) or (s.user_id =2 and s.reciever_id =1) ) and s.shout_id < 5 order by s.shout_id desc limit 20;
The raw query code being in android -
public Cursor get_friend_shouts_less(String myid, String friend_id, long shout_id) {
open();
Log.d("ListView1", "get less Message myid friend_id shout_id: " + myid + " " + friend_id + " " + shout_id );
Cursor c = db.rawQuery("select s.shout_id, u.user_id, u.image_id , u.firstname, u.lastname, s.shout_msg , i.user_id 'r_user_id' , i.image_id 'r_img_id', i.firstname 'r_firstname', i.lastname 'r_lastname', s.rec_time from shouts s left join users u " +
"on s.user_id = u.user_id left join users i on s.reciever_id = i.user_id" +
" where ((s.user_id =? and s.reciever_id =?) or (s.user_id =? and s.reciever_id =?) ) and s.shout_id < ? order by s.shout_id desc limit 60;", new String[]{myid, friend_id, friend_id, myid , String.valueOf(shout_id)});
return c;
}
Glad it worked, now my official Answer:
A SQL LEFT JOIN Operation is equal to an karthesian product AxB, which can lead to rows wih the same content. In "simple": using GROUP BY merges those identical rows.
Sorry I don't know much about SQL syntax. Basically, I have the following columns in my table:
ID GAME DRAW NUMBER
x 0 23
x 1 34
x 0 24
x 1 35
x 1 33
I want to get the max DRAW NUMBER based on the GAME column value.
For example, if I select GAME 1, I want to get a DRAW NUMBER of 35 (i.e., highest draw number for game 1 is 35)
The best I have come up with is the following:
String table = "xxx", col = "DRAW NUMBER", game_col = "GAME";
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.query(table, null, col+"=(SELECT MAX("+col+") FROM " + table + " GROUP BY " + game_col + ")", null, null, null, null);
.
Also I would like to get the count of a specific game based on the GAME value.
This is what I have so far:
int game_val = 1, row_count;
String table = "xxx", game_col = "GAME";
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery("SELECT COUNT(*) FROM " + table + " WHERE " + game_col + " = " + game_val + "", null);
row_count = c.getCount();
Thank you in advance!
You can use rawQuery
For specific game, just replace the 1 with a variable (edited: removed group by, not needed in this one, thanks Bae)
Cursor c = db.rawQuery("SELECT max(DRAW NUMBER) FROM xxx WHERE GAME = 1", null);
For list of all max numbers for all games
Cursor c = db.rawQuery("SELECT GAME, max(DRAW NUMBER) FROM xxx GROUP BY GAME", null);
You only need this query
Cursor cursor = db.rawQuery("SELECT MAX(DRAW_NUMBER) FROM your_table_here WHERE GAME = 1, null);
For list you can use the query that Hrusilov told you.
Please let me know how to delete n-rows in android sqlite database. I used this code:
String ALTER_TBL ="delete from " + MYDATABASE_TABLE +
"where"+KEY_ID+"in (select top 3"+ KEY_ID +"from"+ MYDATABASE_TABLE+"order by _id );";
sqLiteDatabase.execSQL(ALTER_TBL);
But it shows an error.
03-21 13:19:39.217: INFO/Database(1616): sqlite returned: error code = 1, msg = near "in": syntax error
03-21 13:19:39.226: ERROR/Database(1616): Failure 1 (near "in": syntax error) on 0x23fed8 when preparing 'delete from detail1where_id in (select top 3_idfromdetail1order by _id );'.
String ALTER_TBL ="delete from " + MYDATABASE_TABLE +
" where "+KEY_ID+" in (select "+ KEY_ID +" from "+ MYDATABASE_TABLE+" order by _id LIMIT 3);";
there is no "top 3" command in sqlite I know of, you have to add a limit
watch out for spaces when you add strings together : "delete from" + TABLE + "where" = "delete frommytablewhere"
This approach uses two steps to delete the first N rows.
Find the first N rows:
SELECT id_column FROM table_name ORDER BY id_column LIMIT 3
The result is a list of ids that represent the first N (here: 3) rows. The ORDER BY part is important since SQLite does not guarantee any order without that clause. Without ORDER BY the statement could delete 3 random rows.
Delete any row from the table that matches the list of ids:
DELETE FROM table_name WHERE id_column IN ( {Result of step 1} )
If the result from step 1 is empty nothing will happen, if there are less than N rows just these will be deleted.
It is important to note that the id_column has to be unique, otherwise more than the intended rows will be deleted. In case the column that is used for ordering is not unique the whole statement can be changed to DELETE FROM table_name WHERE unique_column IN (SELECT unique_column FROM table_name ORDER BY sort_column LIMIT 3). Hint: SQLite's ROWID is a good candidate for unique_column when deleting on tables (may not work when deleting on views - not sure here).
To delete the last N rows the sort order has to be reversed to descending (DESC):
DELETE FROM table_name WHERE unique_column IN (
SELECT unique_column FROM table_name ORDER BY sort_column DESC LIMIT 3
)
To delete the Nth to Mth row the LIMIT clause can be extended by an OFFSET. Example below would skip the first 2 rows and return / delete the next 3.
SELECT unique_column FROM table_name ORDER BY sort_column LIMIT 3 OFFSET 2
Setting the LIMIT to a negative value (e.g. LIMIT -1 OFFSET 2) would return all rows besides the first 2 resulting in deletion of everything but the first 2 rows - that could also be accomplished by turning the SELECT .. WHERE .. IN () into SELECT .. WHERE .. NOT IN ()
SQLite has an option to enable the ORDER BY x LIMIT n part directly in the DELETE statement without a sub-query. That option is not enabled on Android and can't be activated but this might be of interest to people using SQLite on other systems:
DELETE FROM table_name ORDER BY sort_column LIMIT 3
It seems that you've missed some spaces:
"where"+KEY_ID+"in..
must be:
"where "+KEY_ID+" in...
Furthermore you need to use the limit statement instead of top:
I'll do:
db.delete(MYDATABASE_TABLE, "KEY_ID > "+ value, null);
you can try this code
int id;
public void deleteRow(int id) {
myDataBase.delete(TABLE_NAME, KEY_ID + "=" + id, null);
}
String id;
public void deleteRow(String id) {
myDataBase.delete(TABLE_NAME, KEY_ID + "=\" " + id+"\"", null);
}
It is a bit long procedure but you can do it like this
first get the ids column of table from which which you want to delete certain values
public Cursor KEY_IDS() {
Cursor mCursor = db.rawQuery("SELECT KEYID " +
" FROM MYDATABASE_TABLE ;", null);
if (mCursor != null)
{
mCursor.moveToFirst();
}
return mCursor;
}
Collect it in an array list
ArrayList<String> first = new ArrayList<String>();
cursor1 = db.KEY_IDS();
cursor1.moveToFirst();
startManagingCursor(cursor1);
for (int i = 0; i < cursor1.getCount(); i++) {
reciv1 = cursor1.getString(cursor1
.getColumnIndex(DBManager.Player_Name));
second.add(reciv1);
}
and the fire delete query
for(int i = 0 ;i<second.size(); i++)
{
db.delete(MYDATABASE_TABLE KEYID +"=" + second.get(i) , null);
}
Delete first N (100) rows in sqlite database
Delete from table WHERE id IN
(SELECT id FROM table limit 100)
You can make use of the following mode: (in addition to the response provided by "zapl").
**DELETE FROM {Table-X} WHERE _ID NOT IN
(SELECT _ID FROM {Table-X} ORDER BY _ID DESC/ASC LIMIT (SELECT {Limit-Column} FROM {SpecificationTable}) );**
Where {Table-X} refers to the table you want to delete, _ID is the main unique-column
DESC/ASC - Based on whether you want to delete the top records or the last records, and finally in the "LIMIT" clause, we provide the "n" factor using another query, which calls in the {Limit-Column} from {SpecificationTable}: Which holds the value against which you want to delete them.
Hope this helps out someone.
Happy Coding.
public Cursor fetchAllPBs() {
String sql = "SELECT * FROM " + CAPTURES_TABLE + " GROUP BY " + KEY_CAPTURES_SPECIES
+ " ORDER BY " + KEY_CAPTURES_POUNDS + " DESC, " + KEY_CAPTURES_OUNCES + " DESC, " + KEY_CAPTURES_DRAMS + " DESC;";
Cursor c = mDb.rawQuery(sql, null);
if(c != null) {
c.moveToFirst();
}
return c;
}
Hi,
I want the above query to return me the user's personal best for each species, that is, the heaviest item within each species. Testing it properly recently I've realised a problem. I'm still relatively new to SQL with this project...
Say I add a 'Chub' to my database of 7lb 6oz 0drms, then add another of 7lb 2oz 0drms - it will return the more recently added fish as the PB and not the biggest (the 7lb 2oz one). However if I then add another Chub of 8lb 0oz 0drms it will return the 8lb fish - it seems it's not properly ordering them by the Ounces and probably by that I assume the drams too.
Can anyone see what's wrong here and suggest a solution?
Many thanks
First, you need a subquery to determine the heaviest fish per species.
Second, your weight is split in 3 columns, so you need to add them in someway. I choose to just add them with multiplication, should be sufficient for getting the max.
SELECT *
FROM CAPTURES_TABLE AS C1
WHERE (100*Pounds+10*Ounces+Drams) =
(SELECT MAX(100*Pounds+10*Ounces+Drams)
FROM CAPTURES_TABLE AS C2
WHERE C2.SPECIES=C1.SPECIES)
ORDER BY pounds DESC, ounces DESC, drams DESC
More of a comment, but I need more space...
If I simplify your query it looks like:
SELECT * FROM table1 WHERE species = species_id
ORDER BY pounds DESC, ounces DESC, drams DESC LIMIT 1
Provided that species is not a unique field, the query is fine.
It looks like the problem is that when adding a new fish you are not adding, but actually replacing the fish, try and remove the limit 1 and see if all fish show up.
The ordering clauses are definitly correct.