How to Perform the following query using Greendao ? - android

I have 2 tables A and B.
Table A contains names and table B contains selected names.
Now I would like to perform the following query on these tables using greendao, Please let me know if it is possible and if it is not are there any alternatives (maybe a raw query).
select *
from A inner join B
on A.nameid = B.nameid
Also, Table A columns: id, nameid, name
and Table B columns: id, nameid, name, rating

I think this might help.
You can use the raw query as a fake join. And you get all you want in the Query object
Query query = ATableDao.queryBuilder().where(
new StringCondition("nameid IN " +
"(SELECT nameid FROM B_Table )").build();
Since "nameid" doesn't seems to be a unique identifier in your sample. I won't suggest to use Relations to solve this issue. If you are try to use Relations, you can find my previous answer here.

Try this:
List<ATableObj> listATableObj = ATableDao.queryRawCreate(", BTable BT
WHERE BT.nameid = T.nameid").list();

If you use greendao this works differntly:
Instead of your query you select rows from table a (or b) and if you need a field of b (or a) you call getB() (or getA()) to get the corresponding row of that table.
If you have rows in table a that have no match in table b and you have rows in table b that have no match in a and you onlly want to select everything that has matches uin both tables, you would have to do a raw query to filter the rows of a (or b).

Related

Sort in GreenDAO

Raw query:
SELECT * FROM SAVED_JOB2 S, JOB J WHERE J._id=S._id ORDER BY DATE_SAVED DESC
How can I achieve sort for column in JOIN table. I have tried:
QueryBuilder<Job> queryBuilder = daoSession.queryBuilder(Job.class);
queryBuilder.join(JobDao.Properties.Id, SavedJob2.class, SavedJob2Dao.Properties.Id);
List<Job> list = queryBuilder1.list();
This normal JOIN works perfect. But I need to sort for date_saved column in table SavedJob.
I tried to add this line:
queryBuilder.orderDesc(SavedJob2Dao.Properties.date_saved);
But this line returns this error:
Property 'date_saved' is not part of com.xxx.xxx.db.JobDao
Table JobDao:
id (PK)
title
description
requirements
allowance
type
status
Table SavedJobDao:
id (PK autoincrement)
j_id (FK to JabDao)
date_saved
status
You don't need to do any JOIN with greenDao. It works with objects, so in your savedJob you should have an object Job instead job_id.
So you can order by date_saved, but searching in savedJob only, you don't need either JOIN.
There are a lot of examples. And the official doc is awesome!.

Android SQLite getting records from one table based on another

Please excuse me if its a repeated question. I tried searching here and at google but I couldn't exactly find what I wanted.
I have got two tables A & B.
Table A Fields : id, name, description, rating.
Table B Fields : id, aId (linked to table A), customerId, recommended.
Table A contains my data items for which I'm storing average cumulative ratings provided by users.
Table B stores another attribute for data of Table A. It stores the recommended bit (1 for recommended & 0 for non-recommended).
I want to list all the data from Table A but I want to sort them using recommended bit from Table B. So, if there are 10 records in Table A and 2 records in Table B, while listing all those 10 records, the two from Table B should come first and then the others from Table A. It doesn't matter whether the recommended bit value is a 0 or a 1. While listing the other 8 records from Table A, I want to list the records based on their rating in descending order.
Can someone please guide me in writing this sqlite query for Android app? Thanks in advance!
The left join adds the recommended field to the result set (with a value of NULL if there is no matching B record).
The expression recommended IS NULL or EXISTS(...) returns either 0 or 1:
SELECT DISTINCT A.*
FROM A LEFT JOIN B ON A.id = B.aId
ORDER BY B.recommended IS NULL,
A.rating DESC
Alternatively:
SELECT *
FROM A
ORDER BY NOT EXISTS (SELECT 1
FROM B
WHERE B.aId = A.id),
rating DESC

Column index order SQLite creates table

This is the query that I use to create a table
create table site_table(
_id integer primary key autoincrement,
name_site text,
url text,
login text,
pass text
);
I called Cursor.getColumnNames() and noticed that columns order are id, login, pass, name, url.
So, if I want a value I have to get it by the index Cursor.getString(index). Until I debugged I was messing up calling the wrong index, but now I wonder, why SQLite saves that way? Why it does not follow that way I created id, name_site, url, login and pass?
Thanks
So, if I want a value I have to get it by the index
Cursor.getString(index)
So for example for this reason you should always use
c.getString(c.getColumnIndex("ColName")); // or better getColumnIndex(CONSTANT)
This method saves all of us and ensure that you never get wrong results. Generally this method is recommended and also storing COLUMN_NAMES as CONSTANTS in separated class is very, very useful and efficient practise.
Note: Order depends on projection i.e. select name, lastname from table
That data is ordered by the order your requested it in your query, not the order you created the table with. So you probably changed the order in your query that generated said cursor.
Columns order in your cursor depends on projection. To be sure you use correct column index use c.getString(c.getColumnIndexOrThrow("COLUMN_NAME")) where c is your cursor.
I just made the experience first hand:
The indices of the columns of the cursor as a result of a
SELECT * FROM mytable WHERE ...
query have sometimes (not always) a different order that what SQLITE Database Browser shows as column order in the Database Structure tab. So referencing the columns via getColumnIndex seems to be the only safe way.

Sorting in SQLite

I have a database and I want to sort it. I came across several code that selects a sorted data but does not modify the database in itself.
I came across..
So how do I sort a database?
You don't sort tables in relational database.
You create index on them. And use ORDER BY in your query. That way your query result will be sorted.
When creating database create index on column to have better query performance:
CREATE INDEX sorted_idx ON table_name(indexed_column ASC);
more about indexes:
http://www.sqlite.org/lang_createindex.html
Then in code select using ORDER BY
db.rawQuery("SELECT * FROM table_name ORDER BY indexed_column ASC", null);
If you mean by 'sort a database' to simple sort a table,
Create temp table as sorted select, eg you have unsorted table1 a you want to sort it by column1 then do this:
CREATE TABLE temp_table1
AS SELECT *
FROM table1
ORDER BY column1;
Drop the original table.
Rename temp_table1 to table1.

Can you delete columns in an SQLite database?

The Android app that I am currently working on dynamically adds columns to an SQLite database. The problem I have is that I cannot figure out a way to remove these columns from the database.
If I add column A, B, C, D, and E to the database, is it possible to later remove column C?
I have done a lot of looking around and the closest thing I could find was a solution that requires building a backup table and moving all the columns (except the one to be deleted) into that backup table.
I can't figure out how I would do this, though. I add all the columns dynamically so their names are not defined as variables in my Java code. There doesn't seem to be a way to retrieve a column name by using Android's SQLiteDatabase.
SQLite has limited ALTER TABLE support that you can use to add a column to the end of a table or to change the name of a table.
If you want to make more complex changes in the structure of a table, you will have to recreate the table. You can save existing data to a temporary table, drop the old table, create the new table, then copy the data back in from the temporary table.
For example, suppose you have a table named "t1" with columns names "a", "b", and "c" and that you want to delete column "c" from this table. The following steps illustrate how this could be done:
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(a,b);
INSERT INTO t1_backup SELECT a,b FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a,b);
INSERT INTO t1 SELECT a,b FROM t1_backup;
DROP TABLE t1_backup;
COMMIT;
SQLite doesn't support a way to drop a column in its SQL syntax, so its unlikely to show up in a wrapper API. SQLite doesn't often support all features that traditional databases support.
The solutions you've identified make sense and are ways to do it. Ugly, but valid ways to do it.
You can also 'deprecate' the columns and not use them by convention in newer versions of your app. That way older versions of your app that depend on column C won't break.
Oh... just noticed this comment:
The app is (basically) an attendance tracking spreadsheet. You can add
a new "event" and then indicate the people that attended or didn't.
The columns are the "events".
Based on that comment you should just create another table for your events and link to it from your other table(s). You should never have to add columns to support new domain objects like that. Each logical domain object should be represented by its own table. E.g. user, location, event...
Was writing this initially. Will keep it if you're interested:
Instead of dynamically adding and removing columns you should consider using an EAV data model for that part of your database that needs to be dynamic.
EAV data models store values as name/value pairs and the db structure never needs to change.
Based on your comment below about adding a column for each event, I'd strongly suggest creating a second table in which each row will represent an event, and then tracking attendance by storing the user row id and the id of the event row in the attendance table. Continually piling columns onto the attendance table is a definite anti-pattern.
With regards to how to find out about the table schema, you can query the sqlite_master table as described in this other SO question - Is there an SQLite equivalent to MySQL's DESCRIBE [table]?
As per SQLite FAQ, there is only limited support to the ALTER TABLE SQL command. So, the only way you can do is that ou can save existing data to a temporary table, drop the old table, create the new table, then copy the data back in from the temporary table.
Also you can get the column name from the database using a query. Any query say "SELECT * FROM " gives you a cursor object. You can use the method
String getColumnName(int columnIndex);
or
String[] getColumnNames();
to retrieve the names of the columns.

Categories

Resources