I'm trying to build a query like this with ormLite:
SELECT `classA`.*
FROM `classA`
LEFT JOIN `classB` ON `classA`.`idField` = `classB`.`fkField`
WHERE `classB`.`dateField` >= '2015-11-16';
The dateField on classB looks like this:
#DatabaseField
private Date dateField;
So the date is persisted in ormLite's default format (e.g '2012-07-13 00:00:00.000000')
This is my approach in ormLite:
QueryBuilder<ClassA, Long> qbA = mDbHelper.getClassADao().queryBuilder();
QueryBuilder<ClassB, Integer> qbB = mDbHelper.getClassBDao().queryBuilder();
qbClassB.where().ge("dateField", new DateTime().minusDays(100).toDate());
qbA.leftJoin(qbB);
List<ClassA> list = qbA.query();
LogCat:
D/BaseMappedStatement: prepared statement 'SELECT `classA`.* FROM `classA` LEFT JOIN `classB` ON `classA`.`idField` = `classB`.`fkField` WHERE `classB`.`dateField` >= ? ' with 1 args
D/StatementExecutor: query of 'SELECT `classA`.* FROM `classA` LEFT JOIN `classB` ON `classA`.`idField` = `classB`.`fkField` WHERE `classB`.`dateField` >= ? ' returned 0 results
The raw query works fine and returns the desired results.
The ormLite query returns an empty resultList.
Does anyone have any idea of what I'm doing wrong?
Related
I have a rather big query that is returning data when executed outside android while returning nothing when executed within android.
I split the query in several pieces and determined that the union was ok.
I tried on a smaller set of data with the same behavior.
I've tested with different hardware and API versions.
I'm using the rawQuery method with constant values.
http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#rawQuery(java.lang.String, java.lang.String[])
This query was meant to replace a FULL OUTER JOIN which is not currently supported.
SELECT IFNULL(stype, gtype) AS type, IFNULL(sdate, gdate) AS date, IFNULL(sroute, groute) AS route FROM (
SELECT sp.type AS stype, sp.date AS sdate, -1 AS gtype, gp.date AS gdate, sp.route AS sroute, gp.route AS groute
FROM Sensor_Point AS sp LEFT JOIN GPS_Point AS gp ON gp._id IS NULL AND sp.sent=0 AND sp.route=gp.route AND sp.route=1
UNION ALL
SELECT sp.type AS stype, sp.date AS sdate, -1 AS gtype, gp.date AS gdate, sp.route AS sroute, gp.route AS groute
FROM GPS_Point AS gp LEFT JOIN Sensor_Point AS sp ON sp._id IS NULL AND gp.sent=0 AND sp.route=gp.route AND gp.route=1
) WHERE route=1 ORDER BY date ASC LIMIT 255
Any hints would be greatly appreciated.
Update:
Look's like the problem is finally with the query parameters, if I set it this way:
String[] args = new String[3];
args[0] = args[1] = args[2] = "1";
Cursor data dataBase.rawQuery(SELECT_POINTS, args);
It doesn't work, while it works when hardcoding values directly in the query.
Cursor data = dataBase.rawQuery(SELECT_POINTS, null);
In the Android database API, all query parameters are strings.
(This is a horrible design mistake.)
Your query corresponds to:
... AND sp.route='1'
Try to convert the parameter strings back into a number like this:
... AND sp.route = CAST(? AS INT)
or just put the number directly into the query string.
I want to select a random row from the realm table. Something like -
SELECT * FROM table ORDER BY RANDOM() LIMIT 1;
Something like this would do, yes?
Random random = new Random();
RealmResults<YourTable> list = realm.where(YourTable.class).findAll();
YourTable yourTable = list.get(random.nextInt(list.size()));
Depends on what you want to do:
Do you want to get a random row from a table?
Or A (random) row from a random table?
I guess you mean the former:
If you have an id in your table, you could just:
SELECT * FROM table b WHERE id = FLOOR(RAND() * (3 - 0 + 1)) + 0
You should place a min and max here like so:
FLOOR(RAND() * (<max> - <min> + 1)) + <min>
(as found here)
SWIFT 5
I do it this way and it works perfect:
let results = realm.objects(MyObject.self) // Get all the objects
let randomIndex = Int.random(in: 0 ..< results.count) // Get a random number within the number of objects returned
let randomObject = results[randomIndex] // Get a random object
Here's how I do it in .NET, takes 7ms for 70K entries.
public IEnumerable<Entry> GetRandomEntries()
{
var randomizer = new Random();
var entries = GetRealmInstance().All<Entry>().AsEnumerable();
// Takes random entries and shuffles them to break the natural order
var randomEntries = entries
.OrderBy(x => randomizer.Next(0, DbQueryRandomEntriesLimit))
.Take(DbQueryRandomEntriesLimit)
.OrderBy(entry => entry.GetHashCode());
return randomEntries;
}
I use AsEnumerable() to allow using .Select in LINQ
String query =String.format("SELECT * FROM realm ORDER BY %d LIMIT 1", random());
databaseHelper = new DatabaseHelper(this);
database = databaseHelper.getWritableDatabase();
Cursor cursor = database.execSQL(query);
It works assuming that you have a class DatabaseHelper which extends SQLiteOpenHelper
Hi I need to use order by max(columnName) in ORMLite. I have the SQL query but I need to know how this query is used. This is my query:
SELECT * FROM table where place = 'somePlace' group by name
order by MAX (statusDate)
statusDate column contains date in "yyyy-dd-mm" format. The result I got is the list with recentDates.
Use a query builder, and function where and orderBy to preoceed
QueryBuilder<YourObject, Integer> q = yourDaoObject.queryBuilder();
Where<YourObject, Integer> wh = q.where();
wh.eq("place", "some_place");
q.orderBy("statusDate", false);
List<YourListOfObects> yourList = q.query();
But before that you should store a long instead to store your Date https://stackoverflow.com/a/6993420/2122876
i got same names with different dates and i need only the recent date.
If you are trying to get element from Table with the maximum statusDate then you should be doing an descending order-by with a limit of 1. Something like:
QueryBuilder<Foo, Integer> qb = fooDao.queryBuilder();
qb.where().eq("place", "some_place");
qb.orderBy("sttusDate", false); // descending sort
// get the top one result
qb.limit(1);
Foo result = qb.queryForFirst();
I did something like this. Please create your own query builder on the first line.
QueryBuilder<MyRowObject, Integer> queryBuiler = "Get Query builder" //getDaoXXX().queryBuilder();
MyRowObject firstLatestRow = queryBuiler.orderBy("dateColoumn", false).queryForFirst();
Hope this helps
I have a rather big query that is returning data when executed outside android while returning nothing when executed within android.
I split the query in several pieces and determined that the union was ok.
I tried on a smaller set of data with the same behavior.
I've tested with different hardware and API versions.
I'm using the rawQuery method with constant values.
http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#rawQuery(java.lang.String, java.lang.String[])
This query was meant to replace a FULL OUTER JOIN which is not currently supported.
SELECT IFNULL(stype, gtype) AS type, IFNULL(sdate, gdate) AS date, IFNULL(sroute, groute) AS route FROM (
SELECT sp.type AS stype, sp.date AS sdate, -1 AS gtype, gp.date AS gdate, sp.route AS sroute, gp.route AS groute
FROM Sensor_Point AS sp LEFT JOIN GPS_Point AS gp ON gp._id IS NULL AND sp.sent=0 AND sp.route=gp.route AND sp.route=1
UNION ALL
SELECT sp.type AS stype, sp.date AS sdate, -1 AS gtype, gp.date AS gdate, sp.route AS sroute, gp.route AS groute
FROM GPS_Point AS gp LEFT JOIN Sensor_Point AS sp ON sp._id IS NULL AND gp.sent=0 AND sp.route=gp.route AND gp.route=1
) WHERE route=1 ORDER BY date ASC LIMIT 255
Any hints would be greatly appreciated.
Update:
Look's like the problem is finally with the query parameters, if I set it this way:
String[] args = new String[3];
args[0] = args[1] = args[2] = "1";
Cursor data dataBase.rawQuery(SELECT_POINTS, args);
It doesn't work, while it works when hardcoding values directly in the query.
Cursor data = dataBase.rawQuery(SELECT_POINTS, null);
In the Android database API, all query parameters are strings.
(This is a horrible design mistake.)
Your query corresponds to:
... AND sp.route='1'
Try to convert the parameter strings back into a number like this:
... AND sp.route = CAST(? AS INT)
or just put the number directly into the query string.
I have two entities: EntityA and EntityB. EntityB has a foreign field of EntityA:
#DatabaseField(foreign=true, columnName=ENT_A_NAME)
private EntityA entityA;
Now I want to query all entries of EntityB where EntityA is null. So I've made the following query:
bDao.queryBuilder().where().isNull(EntityB.Ent_A_NAME).prepare();
If I execute the query I get an empty result set back.
If I execute queryAll() I see that the entries of EntityB have always an associated Order-Object with all values set to null/0.
How can I execute my query?
I'm not sure #Toni4780. The following test case works for me. I don't see anything that you are doing wrong.
In the table for EntityB, ORMLite actually stores the id of the EntityA so I am wondering if it is null or 0. Have you tried the following?
bDao.queryBuilder().where().eq(EntityB.Ent_A_NAME, 0).prepare();
or both:
bDao.queryBuilder().where().isNull(EntityB.Ent_A_NAME).
or().eq(EntityB.Ent_A_NAME, 0).prepare();
Here's my unit test code that works:
Dao<Order, Integer> orderDao =
DaoManager.createDao(connectionSource, Order.class);
TableUtils.createTable(connectionSource, Order.class);
int numOrders = 10;
for (int orderC = 0; orderC < numOrders; orderC++) {
Order order = new Order();
order.val = orderC;
assertEquals(1, orderDao.create(order));
}
List<Order> results = orderDao.queryBuilder().where()
.isNull(Order.ACCOUNT_FIELD_NAME).query();
assertNotNull(results);
assertEquals(numOrders, results.size());