How to get rows from same table with different conditions - android

I want to get data from same table with different conditions. I am using sqlite in android studio.
**ID Name Role**
1 Emma Manager
2 Olivia Manager
3 Ava Manager
4 Isabella Sales officer
5 Sophia Sales Officer
6 Charlotte Sales Officer
7 Mia Clerk
8 Amelia Clerk
Assume this table, I have different types of roles and different numbers of persons in a role. I want to select 2 persons from each role.
Select * from employeeTable where role = 'Manager' LIMIT 2
Select * from employeeTable where role = 'Sales officer' LIMIT 2
Select * from employeeTable where role = 'Clerk' LIMIT 2
Simply I want to join the result of these three queries.
Sorry if the childish question. And thanks in advance

With row_number() window function:
select t.id, t.name, t.role
from (
select *, row_number() over (partition by role) rn
from employeeTable
) t
where t.rn <= 2
You can also define:
partition by role order by name
or:
partition by role order by id
instead of just:
partition by role
to get specific rows in the results.
See the demo.
Results:
| ID | Name | Role |
| --- | -------- | ------------- |
| 7 | Mia | Clerk |
| 8 | Amelia | Clerk |
| 1 | Emma | Manager |
| 2 | Olivia | Manager |
| 4 | Isabella | Sales Officer |
| 5 | Sophia | Sales Officer |

Try is query and check if working:
Select * from employeeTable where role = 'Manager' LIMIT 2
UNION ALL
Select * from employeeTable where role = 'Sales officer' LIMIT 2
UNION ALL
Select * from employeeTable where role = 'Clerk' LIMIT 2

Related

Alternatives to LEAD and LAG in SQLite

I need to find an alternative to LAG and LEAD for finding the previous and next entry in my table in SQLite since those are not support in the version used (updating is not an option).
But I also cant use the value I order by, since it can be a date and therefore can be identical on multiple entries.
Since the table has to be sorted by date, using the ID isn't an option either.
It'd be great if someone knew an alternative way of dealing with this issue, since after more than an hour of searching and trying I am out of ideas.
Edit:
The important columns to my use case are:
_id booking_date
1 2017:11-21
3 2017:11-21
4 2017:11-21
5 2017:11-21
2 2017:11-22
6 2017:11-22
7 2017:11-22
...
_id is the primary key.
The bookings need to be sorted by date.
It is possible for multiple bookings to have the same date.
Bookings with the same date are sorted by their ids (See id 2, 6 and 7 in the give n example)
I need a way to query the entry before and after an entry by its id.
For example for _id=6 the I need a query that selects the row with _id=2 and a query that selects the row with _id=7.
Alternatively a query single query that selects both will work just as good.
I do not need you to provide an entire query, but rather an approach to this issue.
Try something like that, this retrieves previous and next id of a given record using your sort order (by date+id) - assumming that id is the primary key, you can retrieve other columns od prev-next records using these ids:
SELECT *,
(SELECT id FROM t t1
WHERE t1.booking_date < t.booking_date
OR t1.booking_date = t.booking_date AND t1.id < t.id
ORDER BY booking_date DESC, ID DESC LIMIT 1 ) prev_id,
(SELECT id FROM t t1
WHERE t1.booking_date > t.booking_date
OR t1.booking_date = t.booking_date AND t1.id > t.id
ORDER BY booking_date , ID LIMIT 1 ) next_id
FROM t
order by booking_date, id
Demo: http://www.sqlfiddle.com/#!5/17631/2
| id | booking_date | prev_id | next_id |
|----|--------------|---------|---------|
| 1 | 2017-11-21 | (null) | 3 |
| 3 | 2017-11-21 | 1 | 4 |
| 4 | 2017-11-21 | 3 | 5 |
| 5 | 2017-11-21 | 4 | 2 |
| 2 | 2017-11-22 | 5 | 6 |
| 6 | 2017-11-22 | 2 | 7 |
| 7 | 2017-11-22 | 6 | (null) |
If the table looked like this, the final select would be fairly trivial.
_id booking_date seq
1 2017:11-21 1
3 2017:11-21 2
4 2017:11-21 3
5 2017:11-21 4
2 2017:11-22 1
6 2017:11-22 2
7 2017:11-22 3
seq being the number of rows in the same booking_date with smaller id. You could create a virtual view with this structure to drive the main select.
This is a possible approach. Since you were not soliciting "an entire query", I leave it up to you how to implement this idea.

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.

Sqlite query in Android to get the last inserted row by other id

I'm using SQLite in Android
I have a table so.
idrow---message---date------transmitter----id_name
1 | Hello | 13-09-14 | Mike | 307
2 | Thanks | 17-09-14 | Louis | 12
3 | Byebye | 18-09-14 | Charlie | 879
4 | Hello | 18-09-14 | Mike | 307
5 | bllaaa | 18-09-14 | Mike | 307
6 | Nice | 19-09-14 | Charlie | 879
7 | Great | 19-09-14 | Mike | 307
I want to get the last inserted row for each id_name .
For example:
Of id_name 307: 7 | Great | 19-09-14 | Mike |
Of id_name 879 6 | Nice | 19-09-14 | Charlie |
Of Louis 12 2 | Thanks | 17-09-14 | Louis |
I try to use this but does not work as expected
String Query = "Select * from TableName, max(id_row) group by id_name" ;
Your query works only in SQLite 3.7.11 or later, which you will not have before API level 16 (Jelly Bean).
In earlier versions, non-grouped columns are not guaranteed to come from the row that matches the MAX().
You have to look up the maximum ID for each id_name separately, either with a join:
SELECT TableName.*
FROM TableName
JOIN (SELECT MAX(id_row) AS id_row
FROM TableName
GROUP BY id_name
) USING (id_row)
or with IN:
SELECT *
FROM TableName
WHERE id_row IN (SELECT MAX(id_row)
FROM TableName
GROUP BY id_name)
(Both queries work the same.)
Well,you can use the following code too...
SELECT * FROM TableName ORDER BY idrow DESC LIMIT 1
and may be you are getting error because of using id_row instead of idrow
Try This
select * from TableName
where id_row = (SELECT max(id_row) FROM TableName)
order by id_row desc
limit 1

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

About the efficient query for displaying on ListView

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');"

Categories

Resources