Distinct values and count in MySQL - android

I have a table that contains messages that have been saved into a ORM database.I have a messages table and Users table using which I am fetching and saving values.
This is my sql query:
Select DISTINCT ch.user AS _id,
con.name,
con.image,
con.color,
con.contact_id
from messages ch
inner join users con
on con.phone = ch.user
order by ch.timestamp ASC
I also have a boolean field status in the messages table. I want to get the count of all rows that have status = false.
Can it be integrated in my above prepared query, so that I can get all the results in a single query? Or will I need to execute another one for fetching count of rows?

You could use a sub select (check this Fiddle):
Select DISTINCT ch.user AS _id,
con.name,
con.contact_id,
(SELECT COUNT(*)
FROM messages ch2
WHERE status = false AND ch.user = ch2.user) AS MY_COUNT
from messages ch
inner join users con
on con.phone = ch.user
order by ch.timestamp ASC;
Or you you select from the result of the select, what might be better in terms of performance.

Related

Getting the last three records from SQLite database

I have a database from which I would like to take the last 3 records. For example if I had the lines 1,2,3,4,5,6, ... 10,11,12,13,14, I would like 12,13,14 no matter the order (12,13,14 for me is equal to 14,13,12).
I tried to follow another question at this link Android SQLite Query - Getting latest 10 records
but what I get is just showing the first 3 rows of the database.
This is my query
String query2 ="select * from (select * from USERS order by ID ASC limit 3)";
In any case you can sort by rowid descending and get 3 rows:
select * from USERS order by rowid desc limit 3
If you want to sort by a specific column:
select * from USERS order by columnname desc limit 3

How to store only 10 last records to room?

I have some Entity to store my data into ROOM. How to store only 10 last row to my db using room. For now I'n using #Query("SELECT * FROM Entity LIMIT 10") but it's dont looks right
We you want only first 10 or less records in your database then you have to set the id as auto increment and try to delete all those records where the ids doesn't match the first 10 results (after every insertion)
DELETE FROM tableName where id NOT IN (SELECT id from tableName ORDER BY id DESC LIMIT 10)
Here is a link to explore more:-
Limit the amount of rows in a room database
Does it work?
This is the correct way to do it:
SELECT expressions
FROM tables
[WHERE conditions]
[ORDER BY expression [ ASC | DESC ]]
LIMIT number_rows [ OFFSET offset_value ];
And here's a real example:
SELECT contact_id, last_name, first_name
FROM contacts
WHERE website = 'TechOnTheNet.com'
ORDER BY contact_id ASC
LIMIT 5;
I got these from https://www.techonthenet.com/sql/select_limit.php.
There could by slight differences in syntax as I do not know which type of SQL you are using.

SQL Query for timestamp

I had following Table
CREATE TABLE Customer
( `Name` varchar(7), `Address` varchar(55), `City` varchar(15),`Contact` int,`timestamp` int)
;
INSERT INTO Customer
(`Name`,`Address`, `City`, `Contact`,`timestamp`)
VALUES
('Jack','New City','LA',79878458,456125),
('Joseph','New Lane23','LA',87458458,794865),
('Rosy','Old City','Paris',79878458,215125),
('Maria','New City','LA',79878458,699125),
('Jack','New City','LA',79878458,456125),
('Rosy','Old City','Paris',79878458,845125),
('Jack','New Main Street','New York',79878458,555525),
('Joseph','Near Bank','SAn Francisco',79878458,984521)
;
I want to get all customer record with highest timestamp without duplication.
Try the following.
select name,max(timestamp),Address,City,Contact from Customer group by name
I want to get all customer record with highest timestamp without
duplication.
Use DISTINCT operator and ORDER BY clause like
select distinct `Name`,`Address`, `City`, `Contact`,`timestamp`
from customer
order by `timestamp` desc;
In that case you can use JOIN query like
select t1.*
from customer t1 join
(select Name, max(`timestamp`) as maxstamp
from customer
group by Name) xx
on t1.Name = xx.Name
and t1.`timestamp` = xx.maxstamp;
Try this:
SELECT * FROM `customer`
group by name,Address,City,Contact,timestamp
order by timestamp desc
I'm joining the Customer table with itself, the condition c1.timestamp<c2.timestamp on the join clause combined with c2.timestamp IS NULL
will make sure that only the latest record for each person is returned. I put DISTINCT because on your sample data there are two records for Jack with the same timestamp:
SELECT DISTINCT
c1.*
FROM
Customer c1 LEFT JOIN Customer c2
ON c1.Name=c2.Name
AND c1.Contact=c2.Contact -- you might want to remove this
AND c1.timestamp<c2.timestamp
WHERE
c2.timestamp IS NULL
ORDER BY
Name, Address
Please see a fiddle here.

SQLite: Return the most recent 'n' rows per unique value of column 'y'

I have a table with the following schema:
CREATE TABLE table (
msg_id TEXT,
thread_id TEXT,
.
.
.
date INTEGER
)
I need to retrieve the most recent n msg_id per unique value of thread_id. Is there a way to do it using a single query or will I need to query the database to get the most recent distinct thread_ids, then query the database again PER unique thread_id? I recall reading somewhere that multiple database queries can get expensive.
You could use a correlated subquery. For example, for N = 5 :
select *
from YourTable yt1
where 5 <
(
select count(*)
from YourTable yt2
where yt2.thread_id = yt1.thread_id
and yt2.msg_id < yt1.thread_id
)
This is not too fast, so you might be better of with multiple queries.

SQLite query: selecting the newest row for each distinct contact

I'm working with the Android SQLite db, and I have a table with messages in it. Each message has a ContactId. I need to get a list of the newest message associated with each ContactId.
My query looks like this so far:
SELECT * FROM messages GROUP_BY ContactId HAVING ( COUNT(ContactId) = 1 ) ORDER_BY MessageTime DESC
However when I run the query I get this exception:
near "ContactId": syntax error: , while compiling: SELECT * FROM messages GROUP_BY ContactId HAVING ( COUNT(ContactId) = 1 ) ORDER_BY MessageTime DESC
Here's the table definition in case it helps:
create table messages (_id integer primary key autoincrement, ContactId text not null, ContactName text not null, ContactNumber text not null, isFrom int not null, Message text not null, MessageTime int not null);
NOTE: My answer below does not appear to be working as of SQLite 3.7.5, I suggest using the "JOIN" query suggested by Larry.
You are close. What you need to do is sort all the records first, using a subquery table, and then group them. The values that are returned in the result set will be from the last row in each group. So you actually want newer messages to appear at the bottom if you are trying to get the newset message. The "GROUP BY" already ensures you get one row per ContactId.
SELECT * FROM (SELECT * FROM messages ORDER BY MessageTime) GROUP BY ContactId
The HAVING clause is not needed. I haven't used it before but according to the docs the HAVING clause will discard whole groups that don't match, but it doesn't sound like you want any groups discarded, you want results from every ContactId.
Also note there is no underscore in "ORDER BY" or "GROUP BY".
Here are two ways to do it.
This query builds a list of the most recent times for each user, then JOINs that back to the message table to get the message information:
SELECT M1.* FROM messages M1 JOIN
(SELECT ContactId, MAX(MessageTime) AS MessageTime FROM messages GROUP BY ContactId) M2
ON M1.ContactID = M2.ContactID AND M1.MessageTime = M2.MessageTime;
This query does something slightly different. It looks at each message and asks if there exists any later message for the same contact. If not, the row must be the most recent one:
SELECT M1.* FROM messages M1
WHERE NOT EXISTS (SELECT * FROM M2
WHERE M2.ContactID = M1.ContactID AND M2.MessageTime > M1.MessageTime)

Categories

Resources