Following table contains my SQLite-Database on Android:
>>>>> Dumping cursor android.database.sqlite.SQLiteCursor#9f3d273
0 {
id=1543948972569
relationItemID=-1
degree=-1
}
1 {
id=-1
relationItemID=1543948972569
degree=1
}
2 {
id=1543948972569
relationItemID=1543948978808
degree=1
}
3 {
id=1543948978808
relationItemID=1543948972569
degree=-1
}
<<<<<
The SQLite-Query
SELECT id FROM itemsHierarchy
WHERE id = 1543948972569 AND degree BETWEEN 0 AND -128
Returns an empty cursor even though it should find id of first entry.
But if I use '<' instead of 'BETWEEN 0 AND -128' like below, it works.
SELECT id FROM itemsHierarchy WHERE id = 1543948972569 AND degree < 0;
Did I do something wrong or is it a problem of SQLite?
It should be -
SELECT id
FROM itemsHierarchy
WHERE id = 1543948972569
AND degree BETWEEN -128 AND 0
Related
Trying to learn Android studio. And I expect your help on this.I am adding and listing data with sqlite.
for example;
id - name - value
1 - john - 100
2 - mark - 200
3 - john - 150
4 - john - 200
5 - adam - 400
what I want to do, list only names one time.
1 - john
2 - mark
3 - adam
private void showlist() {
ArrayList<DataListItems> contactList = new ArrayList<DataListItems>();
contactList.clear();
String query = "SELECT * FROM data ";
Cursor c1 = sqlHandler.selectQuery(query);
if (c1 != null && c1.getCount() != 0) {
if (c1.moveToFirst()) {
do {
DataListItems contactListItems = new DataListItems();
contactListItems.setid(c1.getString(c1
.getColumnIndex("id")));
contactListItems.setName(c1.getString(c1
.getColumnIndex("name")));
contactListItems.setValue(c1.getString(c1
.getColumnIndex("value")));
contactList.add(contactListItems);
} while (c1.moveToNext());
}
}
c1.close();
DataListAdapter contactListAdapter = new DataListAdapter(
SiteList.this, contactList);
lvCustomList.setAdapter(contactListAdapter);
}
You can use the GROUP BY name to select only one name. However, the id selected would be an arbitrary id for each group (name).
your code could use String query = "SELECT * FROM data GROUP BY name";
If you wanted the first/lowest id per name then you could use min(id) in conjunction with GROUP BY NAME.
your code could use String query = "SELECT min(id) AS id, name, value FROM data GROUP BY name";
You say that your expected result should be
1 - john
2 - mark
3 - adam
That would be more complicated (and perhaps of little use) as the id for adam is 5 not 3 (I assume that is simply a typing error).
as docs say( https://github.com/cloudant/sync-android/blob/master/doc/query.md) im trying to do a query inside a list
look:
query.put("codigo", 4);
result = q.find(query);
for (DocumentRevision revision : result) {
Log.d("QueryTest", "Test1 :" + revision.getBody().toString());
}
return:
{ "codigo":4, "companies":[
{
"id":"b9f19d88-13c0-40e3-89de-63dc787afb4c",
"name":"Filial 0 1488949817178"
},
{
"id":"f17fb098-316e-4d33-a0f7-f5719bf9d62e",
"name":"Filial 1 1488949817178"
} ], "employees":[
{
"codigo":2891,
"id":"cc54fa37-0b64-4108-869a-1303c6176ce5",
"name":"Employee 0 79ed4"
},
{
"codigo":4642,
"id":"19b76bbc-82c7-4295-a385-82ac2d892458",
"name":"Employee 1 e1102"
} ], "id":"ef2d0ebf-50b9-4cd0-9aaf-5389bccaaa56", "nome":"Random 4" }
so its ok
but this query doesnt work:
query.put("employees.codigo", 2891);
first return:
QuerySqlTranslator: No single index contains all of
[{employees.codigo={$eq=2891}}]; add index for these fields to query
efficiently
after created the index:
Index i = q.createJsonIndex(Arrays.<FieldSort>asList(new FieldSort("employees.codigo")), null);
return
QueryExecutor: Projection fields array is empty, disabling project for
this query
so i created the arraylist of fields to filter
List<String> fields = Arrays.asList("codigo");
result = q.find(query, 0 , 0 , fields, null);
nothing returned
adding more one field to filter:
query.put("codigo",4)
query.put("employees.codigo", 2891);
returned: Complain about index
Created another index:
i = q.createJsonIndex(Arrays.<FieldSort>asList(new FieldSort("employees.codigo"), new FieldSort("codigo")), null);
returned: Nothing
whats is wrong?
How can i get document by child and how can i get ONLY the children?
thanks
I think this is unsupported, see the doc on unsupported features, specifically the highlighted entry:
Arrays
Dotted notation to index or query sub-documents in arrays.
Querying for exact array match, { field: [ 1, 3, 7 ] }.
Querying to match a specific array element using dotted notation, { field.0: 1 }.
Querying using $all.
Querying using $elemMatch.
String sql3 = "INSERT INTO temp_d_takingOrder(
HeaderId,
ItemCode,
Qty1,
Qty2,
Qty3,
RegDisc,
ExtraDisc,
OthersDisc,
RegPerc,
ExtraPerc,
OthersPerc)
SELECT
t._id,
m.itemCode,0 AS Qty1,
0 AS Qty2,
0 AS Qty3,
0 AS RegDisc,
0 AS ExtraDisc,
0 AS OthersDisc,
0 AS RegPerc,
0 AS ExtraPerc,
0 AS OthersPerc
FROM m_Route AS m
JOIN t_TakingOrder AS t ON
m.CustId = t.CustId **WHERE t.CustId=?"**;
dataTemp_d_TakingOrder.updateRaw(sql3);
When I used WHERE t.CustId=?, the query is not working. But if I delete that statements, the query is working.. can u help me?
You add a where clause and call updateRaw without providing any value.
I came across a method on Cursor called moveToPrevious().
I had previously read an article which suggested that implementing a backwards version of the C SQLite step command would be hard / impossible:
... asking for an sqlite3_step_backward() button is really like expecting your symbolic debugger to be able to run backwards or to "undo" its execution back to the previous breakpoint. Nobody reasonably expects debuggers to be able to do this, so you shouldn't expect SQLite to be able to sqlite3_step_backward() either.
Is an Android cursor a wrapper around SQLite or some kind of a independent implementation?
How how have thay made this moveToPrevious command?
The Android Cursor class indeed reads all result records into memory first, and then allows you to step through them randomly.
(This is why there is the 1 MB limit on data in a cursor.)
Cursor interface provides random read-write access to the result set returned by a database query. Cursor implementations are not required to be synchronized so code using a Cursor from multiple threads should perform its own synchronization when using the Cursor.
Cursor: Retrieving data from SQLite databases in Android is done using Cursors. The Android SQLite query method returns a Cursor object containing the results of the query.Cursors store query result records in rows and grant many methods to access and iterate through the records.To use Cursors android.database.Cursor must be imported.
http://developer.android.com/reference/android/database/Cursor.html
Check the source here
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.2.2_r1/android/database/Cursor.java/
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.2.2_r1/android/database/AbstractCursor.java/
Look at the line 248 in the link
248 public final boolean moveToPrevious() {
249 return moveToPosition(mPos - 1);
// mPos looks like is the index here which is an int
250 }
moveToPosition
195 public final boolean moveToPosition(int position) {
196 // Make sure position is not past the end of the cursor
197 final int count = getCount();
198 if (position >= count) {
199 mPos = count;
200 return false;
201 }
202
203 // Make sure position isn't before the beginning of the cursor
204 if (position < 0) {
205 mPos = -1;
206 return false;
207 }
208
209 // Check for no-op moves, and skip the rest of the work for them
210 if (position == mPos) {
211 return true;
212 }
getCount()
Returns the current position of the cursor in the row set. The value is zero-based. When the row set is first returned the cursor will be at positon -1, which is before the first row. After the last row is returned another call to next() will leave the cursor past the last entry, at a position of count().
Returns:
the current cursor position.
i run a query with a WHERE
"COMPUTERCLASSROOM_SLOT1 = 0 OR COMPUTERCLASSROOM_SLOT2 = 0 AND COMPUTERCLASSROOM_DONE = 1"
though it return all the row that met a requirement..this is the table rows data
According to column presentation, here are the values of the rows
ROW 1 = 0 0 0
ROW 2 = 1 0 0
ROW 3 = 1 2 1
ROW 4 = 1 3 0
ROW 5 = 1 4 1
ROW 6 = 0 5 1
ROW 7 = 0 0 1
they all return..why is that? if i changed the OR with an AND, it would follow the query, returning ROW 7... its just weird..i need that OR and AND in one query, because my target is to return a row with at least 0 in either SLot1 or Slot2, and DONE = 1
it should be
WHERE (COMPUTERCLASSROOM_SLOT1 = 0 OR COMPUTERCLASSROOM_SLOT2 = 0) AND
COMPUTERCLASSROOM_DONE = 1
As #Jack already pointed out, the problem is because you are not using the parentheses. And hence your query is evaluated logically different from what you are expecting.
Try #JW.'s snippet and it would work perfectly.
WHERE (COMPUTERCLASSROOM_SLOT1 = 0 OR COMPUTERCLASSROOM_SLOT2 = 0) AND (COMPUTERCLASSROOM_DONE = 1)
Underlying cause
AND is evaluated as a multiplication; OR is evaluated as an addition. So according to arithmetic precedence rule (PEMDAS), AND is evaluated before evaluating OR.
Example: 1 OR 0 is 1 + 0 = 1; 1 AND 0 is 1 * 0 = 0;
So
X or X or X and X is grouped automatically as X or X or (X and X).
Use of parenthesis avoids the confusion, as well as makes code more readable.