Ormlite inner join on three tables - android

i want to create an inner join on three tables like this one for example:
SELECT C.Description, D.ItemDescription
FROM OrderDetailStatement AS D
INNER JOIN OrderHeaderStatement AS H
ON H.OrderHeaderStatementRefID = D.OrderHeaderStatementRefID
INNER JOIN customers AS C
ON H.CustomerRefID = C.CustomerRefID
WHERE (D.MixedValue > 1000)
but i'm a little bit confused, could you please provide me a walkthrough?
thanks in advance

ORMLite now supports simple JOIN statements. You can do something like the following:
// start the order header query
QueryBuilder<OrderHeader, Integer> orderHeaderQb = orderHeaderDao.queryBuilder();
QueryBuilder<Customer, Integer> customerQb = customerDao.queryBuilder();
// join with the order query
orderHeaderQb.join(customerQb);
// start the order statement query
QueryBuilder<OrderStatement, Integer> orderStatementQb =
orderStatementDao.queryBuilder();
orderStatementQb.where().gt("mixedvalue", 100);
// join with the order-header query
orderStatementQb.join(orderHeaderQb);
List<OrderStatement> orderStatementQb.query();
Notice, however, that you can only get entities from the query builder using this mechanism. If you want to get your two description fields from different objects then you would have to still use a raw-query.
There is support for "raw queries" including the Dao.queryRaw() method where you can use your own SQL. I suspect you've found them already. Here are the docs for raw queries.

Related

Get Wordpress posts with images link

I want to get wordpress posts with specific category and link of images.
As you know images links save to database in guid column, when post_type = attachment.
and ID of post and post_parent are the same.
Now I want to get posts and join guid column to same ID.
When I added Inner join to combine attachment and post, I got error!
Please help me, if you know the way that I can get post with specific category and images link of each post.
Here is my code:
SELECT
*
FROM
wp_posts p,
wp_postmeta m,
wp_terms t,
wp_term_taxonomy tt,
wp_term_relationships tr,
wp_terms t2,
wp_term_taxonomy tt2,
wp_term_relationships tr2
LEFT JOIN wp_posts AS p2
ON
p.ID = p2.post_parent
WHERE
p.post_type = 'post' AND p.post_status = 'publish'
AND p.ID = tr.object_id
AND t.term_id = tt.term_id
AND tr.term_taxonomy_id = tt.term_taxonomy_id
AND tt.taxonomy = 'category'
AND tt.term_id = t.term_id
AND t.name = 'Fashion'
GROUP BY
p.ID
ORDER BY
id
DESC
MySQL said:
#1054 - Unknown column 'p.ID' in 'on clause'
I suspect that the problem is due to mixing the old school comma syntax with the newer JOIN keyword.
Relevant excerpt from MySQL Reference Manual:
INNER JOIN and , (comma) are semantically equivalent in the absence of a join condition: both produce a Cartesian product between the specified tables (that is, each and every row in the first table is joined to each and every row in the second table).
However, the precedence of the comma operator is less than that of INNER JOIN, CROSS JOIN, LEFT JOIN, and so on. If you mix comma joins with the other join types when there is a join condition, an error of the form Unknown column 'col_name' in 'on clause' may occur. Information about dealing with this problem is given later in this section.
The easiest way to avoid this problem is to ditch the old school syntax for the join operation, use the JOIN keyword instead.
(It's great that the comma syntax is still valid, to provide backwards compatibility with existing SQL. But there's no good reason new development should use the comma syntax.)
Aside from that, there's a couple of big rock issues that stick out to me.
Seems like there's a lot of join conditions missing
Using * for the SELECT list in development can be useful shortcut, but we usually list the expressions we need to return, especially if we want to return id column from multiple tables, where we like to assign a column alias to avid duplicate columns names.
Relying on the non-standard extension to GROUP BY (when only_full_group_by is omitted from sql_mode to return values from "some" row in the collapsed group
Those all look like serious problems to me.
We can re-write the OP query to use JOIN keyword in place of comma syntax, and relocating conditions to the ON clause, this highlights what looks like missing join conditions:
SELECT *
FROM wp_posts p
JOIN wp_postmeta m
-- ON ???
JOIN wp_terms t
ON t.name = 'Fashion'
JOIN wp_term_taxonomy tt
ON tt.term_id = t.term_id
AND tt.taxonomy = 'category'
JOIN wp_term_relationships tr
ON tr.object_id = p.id
AND tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN wp_terms t2
-- ON ???
JOIN wp_term_taxonomy tt2
-- ON ???
JOIN wp_term_relationships tr2
-- ON ??
LEFT
JOIN wp_posts AS p2
ON p2.post_parent = p.id
WHERE p.post_type = 'post'
AND p.post_status = 'publish'
GROUP
BY p.id
ORDER
BY p.id DESC
Where we are going to omit any join condition, and just match all rows to all other rows, then my preference is to include the (optional) CROSS keyword, as an aid the future reader, to signal that the omission of a join condition is by design, and not an oversight.

sqlite select query with foreign key for another table

I am working on a project with xamarin android using the sqlite.net library. I have a select query that will execute and create a collection of custom objects called worker :
var command = conn.CreateCommand("SELECT * FROM tblWorkers");
var results = command.ExecuteQuery<Worker>();
ObservableCollection<Worker> workers = new ObservableCollection<Worker>(results);
return workers;
One of the columns is a foreign key and I need to get a value from that table just wondering what the best way to do that is. The foreign key on the data table tblWorkers is TitleID On that table is a varchar(datatable : tblTitles column : Title - nvarchar) I need to retrieve just wondering what the best way to do that is?
var command = conn.CreateCommand("SELECT * FROM tblWorkers LEFT JOIN tblTitles ON tblWorkers.TitleID = tblTitles.id");
Now, the above will work, but in general you'll want to avoid SELECT * usage. Only get the fields you want. Ideally, something like this...
var command = conn.CreateCommand("SELECT tblWorkers.SomeFieldYouWant, tblWorkers.SomeOtherFieldYouWant, ... , tblTitles.Title FROM tblWorkers LEFT JOIN tblTitles ON tblWorkers.TitleID = tblTitles.id");

ORMLite union operator

I have three tables that I have to present in one Android ListView. To get the data I use the SQL UNION operator to "merge" all three tables together, so that in my ViewBinder I can make each timeline item look distinct.
These items need to be sorted in chronological order. These three tables do not have a common base class.
Here is the SQL that I have in mind:
SELECT * FROM (
SELECT id, startTime as time, username, comment, "CustomerInteraction" FROM CustomerInteraction
UNION
SELECT id, date as time, "" as username, "" as comment, "Sale" FROM Sale
UNION
SELECT id, claimDate as time, username, comment, "TravelClaim" FROM TravelClaim)
ORDER BY time DESC LIMIT 100
How can I express the above query in ORMLite?
I know I can use Dao.executeRaw, but I don't want to populate my entire list in one go. I would much rather use the trick to get the underlying cursor from ORMLite, and then just pass that to my Adapter. (Lazy loading, makes initial display of long lists much faster.)
Is there a way I can do something like Dao.getPreparedQueryFromRaw(String statement) ? Or better yet QueryBuilder.union(QueryBuilder qb)?
You can get a Cursor by calling rawQuery on the SQLiteDatabase. I do something like this:
final SQLiteDatabase db = getHelper().getReadableDatabase();
Cursor cursor = db.rawQuery(MY_SQL_QUERY, null);
You don't need to do anything much more than that.
Is there a way I can do something like Dao.getPreparedQueryFromRaw(String statement) ? Or better yet QueryBuilder.union(QueryBuilder qb)?
The best way to do this with ORMLite is with one of the the queryRaw(...) methods. They return a GenericRawResults class which you can iterate across. The iterator gives you a number of different methods to help with moving around the list.
The problem is that the generic results are not of a certain type so I'm not sure if you can map it into the Android ListView. You can provide a RawRowMapper to queryRaw(...). You can get the mapper for a particular type by using the dao.getRawRowMapper() method.
Hope something here is helpful.

ORMLite how to make '<=' with two columns in same table?

I want to make one query like this:
SELECT * FROM my_table where column_one <= column_two;
With QueryBuilder I can to make where().le(column_one, Object obj), but I want some like where().le(column_one, column_two);
Actually, I want the following query:
SELECT * FROM table_one INNER JOIN table_two ON
table_one.column_foreign_id = table_two.id WHERE table_two.column_one
<= table_two.column_two.
What is the best way?
Thank you for your time.
Yes, you can do it.
Code:
QueryBuilder<Account, String> queryBuilder = accountDao.queryBuilder();
queryBuilder.where().le(Account.COLUMN_ONE_NAME,
new ColumnArg(Account.COLUMN_TWO_NAME));
List<Account> results = queryBuilder.query();
More information here: see 3.7 Using Column Arguments
Have you considered using rawQuery instead?
As the docs say:
The built-in methods available in the Dao interface and the
QueryBuilder classes don't provide the ability to handle all types of
queries.

How do I combine two queries into one?

This is for Android SQLite. I have two queries like this:
select * from table where name='name';
and
select * from table where name!='name' order by name;
I want to create a statement which combines these two queries. I tried union all but I can't do order by one statement and then combine. I tried this:
select * from table where name='name'
union all
select * from table where name!='name' order by name;
All it did is to combine the queries and then order by name. I don't want that. I want to do order by on the second statement first and then combine them.
To put the question differently, here is my data:
Name
a
b
c
d
e
f
g
h
i
j
But I want the output to be:
Name
g
a
b
c
d
e
f
h
i
j
I want to get one row to the top and then order the rest of the rows. Any help is appreciated.
No need to use temporary tables, you need to add an additional column to sort on. Something like this:
select 1, * from table where name='name'
union all
select 2, * from table where name!='name'
order by 1, name;
I don't have a sqlite install right now, but this trick should work. (you may have to add an alias to the first column).
Unless there is some other attribute of the table you can use to provide sorting that allows a join between the two selects as in How to combine two sql queries? then I think you'll have to store the result of the query that should float to the top in a temporary table and then add the sorted results to that table before storing it.
I've never used temporary tables in Android so can't provide an example but as far as I'm aware it's possible.
I'd recommend running the two queries separately and then combining the results in code if that's possible in your situation.
According to the SQLLite docs this cannot be done with a UNION or UNION ALL because those operations must be performed on a simple select, (ones without Order by).
http://www.sqlite.org/lang_select.html
There's probably a very clever way to do this that I don't know, which generally leads me to just do two queries and combine the results in java.
[EDIT] And Jhovanny has the very clever way to do it.
Can't test it right now, but something like this should work:
select t.*, case when name = 'name' then 0 else 1 as o from table t order by o, name;
Then you don't have the two selects nor the union. Assuming you can use a case statement in sqlite on android.

Categories

Resources