About the efficient query for displaying on ListView - android

I'm a beginner of SQL.
I would like to display sqlite data on Android listview. The table has the following structure.
| _id | name | data | ...
---------------------
| 0 | A | abc |
| 1 | B | def |
| 2 | C | ghi | ...
| 3 | D | jkl |
| 4 | E | mno |
So, when the user inputs [C, B, D], I want to display name and data column in user's order.
For example,
ListView
---------------------
C ghi
---------------------
B def
---------------------
D jkl
---------------------
I'm torn between using ArrayAdapter and CursorAdapter now.
Should I do SELECT 3 times, store values in array, and use ArrayAdapter? Or, can fulfill my demands with SELECT once?
Thanks in advance.

It'll be a bit complicated but it can be done in a single query.
SELECT * FROM yourTable
ORDER BY
CASE name
WHEN 'C' THEN 0
WHEN 'B' THEN 1
WHEN 'D' THEN 2
END
You'll have to construct the query according to the user input ofcourse
.
Look more here

You can fulfill your demands with SELECT query. Your query would look like:
String query = "SELECT * FROM yourTable WHERE name IN ('C', 'B', 'D');"

Related

Android Sqlite subquery is not returning all intended results

I am working on a learning app which retrieves data from a local sqlite database. That database has two tables.
The category table which stores the article categories:
+-------------+--------------------------+
| category_id | category_value |
+-------------+--------------------------+
| programming | How To Start Programming |
+-------------+--------------------------+
| math | How To Start Math |
+-------------+--------------------------+
| chemistry | How To Start Chemistry |
+-------------+--------------------------+
The article table which stores the articles themselves:
+-------------+------------+------------------------+
| parent_id | article_id | article_value |
+-------------+------------+------------------------+
| programming | java | Let's learn java |
+-------------+------------+------------------------+
| programming | python | Let's learn python |
+-------------+------------+------------------------+
| math | funcs | Let's learn functions |
+-------------+------------+------------------------+
| math | derivative | Let's learn derivative |
+-------------+------------+------------------------+
| chemistry | lewis | Let's learn Lewis |
| | | structure |
+-------------+------------+------------------------+
Now I did implement a search ability. I want the results to be either the articles who has the searched phrase in their article_value or the ones who has the searched phrase in their parent's category_value. So I used this query in order to do so:
SELECT * FROM article WHERE article_value LIKE '%search_phrase%' OR parent_id = (SELECT category_id FROM category WHERE category_value LIKE '%search_phrase%')
It works fine for the articles part but when it comes to the subquery part it only returns the articles of just one category. Even if there are more qualified categories.
Does a LEFT JOIN do what you want?
SELECT a.*
FROM article a LEFT JOIN
category c
ON c.category = a.article_parent AND
c.category_value LIKE '%search_phrase%'
WHERE a.article_value LIKE '%search_phrase%' OR
c.category IS NOT NULL;
You can do it with EXISTS:
SELECT a.* FROM article a
WHERE a.article_value LIKE '%search_phrase%'
OR EXISTS (
SELECT 1 FROM category c
WHERE c.category_id = a.parent_id
AND c.category_value LIKE '%search_phrase%'
)
See the demo.

How to get all rows grouped by value in particular column and make on specific group first in Cursor in SQLite?

Let's say I have a table with column city_id. I need to get a Cursor which firstly points to all rows with specific value (that I specify) on that column and then points to rest of rows which are again grouped by city_id column?
I have tried:
database.query(DATABASE_TABLE_7, columns, null, null, CITY_ID, null, null);
but it gave only the last rows of each city_id and I'm not able to get rows with specific id first.
Let's say I have a table like this:
| _id | city_name | city_id | ... |
___________________________________________
| 1 | "A" | 1 | ... |
| 2 | "B" | 2 | ... |
| 3 | "A" | 1 | ... |
| 4 | "B" | 2 | ... |
| 5 | "B" | 2 | ... |
| 6 | "C" | 3 | ... |
| 7 | "B" | 2 | ... |
| 8 | "C" | 3 | ... |
For example, required city to be first is city "B", the list needs to be like this:
1 . "B"
2 . "B"
3 . "B"
4 . "B"
5 . "A"
6 . "A"
7 . "C"
8 . "C"
Or
1 . "B"
2 . "B"
3 . "B"
4 . "B"
5 . "C"
6 . "C"
7 . "A"
8 . "A"
The order in which the rest of city groups are shown doesn't matter as long as the rows with required city_id are listed first
have you tried UNION?
use a raw query for that (i am not sure for helper query() ) and other helpers method
try this
select * from locations where city_id=1
union
select * from locations where city_id!=1 order by city_id
use any other value as you like (instead of 1)

Recursive CTE query without top level result in SQLite

I'm currently working on a recursive query on an Android SQLite database. I have a table containing assets, which can form a hierarchy by referring to parents. For example:
AssetId | ParentAssetId 1--2--5
----------------------- | |
1 | NULL | |--6--8
2 | 1 | | |
3 | 1 | | |--9
4 | 1 | |
5 | 2 | |--7
6 | 2 |
7 | 2 |--3
8 | 6 |
9 | 6 |--4--10
10 | 4
I need to find all of the descendents of a given start point, but not including the start point. For example:
1 = 2,3,4,5,6,7,8,9,10
2 = 5,6,7,8,9
6 = 8,9
I managed to get this working using the example from the SQLite page:
SQLite WITH page
WITH RECURSIVE
Child(AssetId) AS (
VALUES (1)
UNION
SELECT Assets.AssetId FROM Assets, Child
WHERE Assets.ParentAssetID = Child.AssetId)
SELECT AssetId FROM Child WHERE AssetId != 1
This works, but I'm not happy regarding the final WHERE clause to filter out the original item. Is there some other way to start the cascade without including the original item?
You could start with the children of the original item:
WITH RECURSIVE
Child(AssetId) AS (
SELECT AssetId FROM Assets WHERE ParentAssetID = 1
UNION ALL
SELECT ...
)
SELECT AssetId FROM Child
This isn't really any simpler.

Table rows as columns?

I have the following two tables and the second one containts a dynamic amount of attributes for each entry of the first table:
people:
_id | name | first | status
----------------------------------
1 | Smtih | Sam | on
2 | Doe | Joe | off
constraints: some people may have no more than in people, some may have 20:
_id | persid | type | value
-------------------------------------------------
1 | 2 | IQ | 90
2 | 2 | bold | yes
... | ... | ... | ...
So as a intermediate result I would like to get this:
_id | name | first | status | IQ | bold | ...
------------------------------------------------ ... more depending on person
2 | Doe | Joe | off | 90 | yes | ...
so that I can eventually select those items with specific attributes e.g.:
`SELECT * FROM <--the above table--> WHERE status = 'off' AND IQ > '75'
I would be fine if those people who do not have the right attributes (in this case IQ) would not even show up in the intermediary table (quicker?).
Sadly, I did not get very far in my own feeble attempts. I guess GROUP_CONCAT should play a role, but can't get it to work.
As always, thank you guys in advance for your time and effort!
As Selvin wrote, if you know all of the types, you can generate a query. But if you add the attributes by the time, you need two queries. The last part in the following code containing the IQ will not work, because IQ is not a column.
SELECT * FROM <--the above table--> WHERE status = 'off' AND IQ > '75'
First of all, you need to get the fixed information.
SELECT _id, name, first, status ...
There you can do your selection (for example by IQ):
SELECT _id, name, first, status FROM wherever WHERE (SELECT value FROM attributes WHERE persid = _id AND type='IQ') > 75
Finally, for each of the selected records you need to get the attributes.
SELECT value FROM attributes WHERE presid=_id_given_by_program

Many-to-Many Query in One Cursor Without Repeating Data

So, I'm going to say that I have three tables as follows:
POSTS POSTS_TAGS TAGS
+-----+-----------+ +---------+--------+ +-----+-------+
| _id | title | | post_id | tag_id | | _id | title |
+-----+-----------+ +---------+--------+ +-----+-------+
| 0 | foo | | 0 | 1 | | 0 | baz |
+-----+-----------+ +---------+--------+ +-----+-------+
| 1 | bar | | 0 | 2 | | 1 | quux |
+-----+-----------+ +---------+--------+ +-----+-------+
| 1 | 0 | | 2 | corge |
+---------+--------+ +-----+-------+
| 1 | 2 |
+---------+--------+
Is there any way to formulate a query with SQLite such that I could then have a cursor with the following data in it:
row1 = <foo, <quux, corge>>
row2 = <bar, <baz, corge>>
As opposed to:
row1 = <foo, quux>
row2 = <foo, corge>
row3 = <bar, baz>
row4 = <bar, corge>
However, I severely doubt that there is anything that will give me precisely that, so I guess my real question is, what is the best way to formulate a query such as this, so that I can pass it back to my activity, and it would be able to return all this data to the activity? Or am I really going to need to iterate through my cursor again afterwards to "pick up" all the extra data and reorganize it myself.
Got the solution:
SELECT posts._id, posts.title, GROUP_CONCAT(tags._id) AS tags_id, GROUP_CONCAT(tags.tag_name) AS tags_name FROM posts
LEFT OUTER JOIN posts_tags ON posts_tags.post_id=posts.post_id
LEFT OUTER JOIN tags ON posts_tags.tag_id=tags.tag_id
GROUP BY posts._id;
Please adapt the query to your problem :)
You can find SQLite documentation about concat(x) and concat(x,separator) here.
Anyway you can also follow my problem on google group.

Categories

Resources