Android SQLite query multiple tables - android

Im trying to do something like this (This is MySQL format)
SELECT q.question_id, q.question, q.answer
FROM relationship r, questions q
WHERE r.cat_id =1
AND r.question_id = q.question_id
LIMIT 0 , 30
So, I got questions stored in one table, then categories in another table. I have the relationship table set up so that a question can be in multiple categories. So say a question has an id of 5, and its in 3 different categories, the relationship table would look like this
relation_id, question_id, category_id
1 5 1
2 5 2
3 5 3
4 6 1
So, say I wanna get all the questions with the cat_id of 1, I should get 2 results. That's basically what I'm trying to do.

If you want all questions with cat_id of 1, then you want this:
select q.question, q.answer
from questions q
join relationship r on q.question_id = r.question_id
where r.cat_id = 1
I've switch to the ANSI join syntax rather than implied join conditions in the WHERE clause because the explicit version helps to avoid certain types of errors; in particular, ANSI joins help avoid accidental cross products and that's what your "MySQL format" query has because you neglected to include a join condition for category. That accidental cross product is almost certainly the source of your "returns each item 3 times" problem.

SELECT q.question, q.answer
FROM questions q
left join category c on q.catID = c.catID
left join relationship r on q.relID = r.relID
Some thing like this will de the trick

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 get distinct from column 1 where column 1 and column 2 meets multiple requirements

I'm not entirely sure how possible this is in a select statement, or if I'm better getting all results and doing checks myself in Android Studio.
I've got 3 tables, a table that stores Recordings, a Table that stores Tags and a table that links the Tags to the Recordings - TagsLink.
The TagsLink table has 2 columns, one that stores the TagsID and one that stores the RecordingsID
What I'm hoping to do is only return RecordingsIDs that meet the selected Tags criteria. So if TagsID 3 is selected, Recordings 1, 2 and 4 are returned. And if TagsID 3 and 4 are selected, it returns only Recordings 2 and 4.
In my mind it's something along the lines of:
SELECT DISTINCT RecordingsID FROM TagsLink WHERE ...
If this isn't entirely possible, any advice on other ways of achieving this (even if it requires restructuring the database) would be greatly appreciated!
With this kind of query:
SELECT
RecordingsID
FROM
TagsLink
WHERE
TagsID IN (3, 4, ...)
GROUP BY
RecordingsID
HAVING COUNT(*) = 2 -- This number must match the number of tag IDs specified in the IN (...) list.
The key is to remember to adjust the count based on the tags you want to filter on.
Other similar and helpful answers here and here and here.
EDIT
To accommodate additional tables, filtering on different columns, use INTERSECT as follows:
SELECT
RecordingsID
FROM
TagsLink
WHERE
TagsID IN (3, 4, ...)
GROUP BY
RecordingsID
HAVING COUNT(*) = 2 -- This number must match the number of tag IDs specified in the IN (...) list.
INTERSECT
SELECT
RecordingsID
FROM
ContactsLink
WHERE
ContactsID IN (100, ...)
GROUP BY
RecordingsID
HAVING COUNT(*) = 1 -- This number must match the number of contacts IDs specified in the IN (...) list.
This should work:
SELECT RecordingsID FROM tagslink WHERE TagsID = 4
Intersect
SELECT RecordingsID FROM tagslink WHERE TagsID = 3
I could not test it with sqlite. However, the function to use is Intersect, not using parentheses that sqlite does not support them

Tree select sqlite [duplicate]

This question already has answers here:
Database Structure for Tree Data Structure [closed]
(5 answers)
Closed 7 years ago.
I am using sqlite in android and need to make an select to get all parent with their child's, for example:
id || parent_id || child_id || name
1 1 1 jhon
2 1 2 helen
3 2 3 barack
4 1 4 manuel
5 3 5 gaga
result should be:
jhon
helen
manuel
barack
gaga
So, I need a reqursive sql, but googling a bit I found that CTE is not supported on sqlite, anyway I can use even an recursive java method to return a list of selected names order by parent asc
Notice that tree depth can be more than 2 levels!
I'm not sure how to interpret your table. Each node has an ID, right; and a (unique) parent_id (pointing to itself for the root node?). What's the child_id? Can't there be multiple children?
When dealing with recursive structures of arbitrary depth, if the tree doesn't change too often, and queries need to be fast, create a supporting table (say, "ancestral_closure") detailing the closure of all parent-child relationships:
ancestor_id, child_id
and make sure it's updated whenever the base table changes (recurse through the base table and add a row for each node that sits below another one). Join with the ancestral_closure table when you need to find all parents and/or children of a node. I don't think sqlite supports stored procedures executed on insert/delete/update triggers, so the update will have to be triggered by hand.
SQL is good at simple relations, not arbitrary graphs.

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

adding the results of two SQlite queries

I want to add the results of two separate counting SQlite queries. Suppose I have 2 tables named entries and scores and have 2 queries:
SELECT COUNT(1) FROM entries WHERE
key NOT IN (SELECT key FROM scores)
SELECT COUNT(1) FROM scores WHERE
value <= threshold
Maybe I could do something like this to get the sum of their results:
SELECT COUNT(1) from (
SELECT key FROM entries WHERE
key NOT IN (SELECT key FROM scores)
UNION ALL
SELECT key FROM scores WHERE
value <= threshold
)
But is this a little too inefficient? This is called pretty often and may interfere with the UI's smoothness.
Thank you.
[EDIT] What I'm actually trying to do:
I'm making an app to help learning vocabulary. The entries table keeps 'static' data about word type, definition, etc. The scores table keeps information about how well you've learned the words (e.g. performance, scheduled next review time)
To check for the number of remaining words to learn/review, I count how many words do not exist in the scores table yet (i.e. never touched) or when the accumulated score is pretty low (i.e. needs reviewing).
The reason I don't merge those 2 tables into 1 (which would make my life much easier) is because sometimes I need to update the entries table either by inserting new words, deleting a few words, or updating their content, and I haven't found a simple way to do that. If I simply do INSERT OR REPLACE, I will lose the information about scores.
I think you're looking for a UNION. A union combines the results from two queries. Try this (sorry it isn't tested, I don't have access to SQLite):
SELECT COUNT(1) FROM
(
SELECT 1
FROM entries
WHERE key NOT IN (SELECT key FROM scores)
UNION ALL
SELECT 1
FROM scores
WHERE scores.value <= threshold
)
After reading the edit in your question explaining what you need to do, I think a JOIN would be more appropriate. This is a way of combining two tables into one query. Something like this:
SELECT COUNT(1)
FROM entries
LEFT JOIN score
ON score.key = entries.key
WHERE score.value <= threshold
OR score.key is null

Categories

Resources