Select rows if column has same value more times - mysql

I have a column named log which contains logging information. I need a query to select all rows in which the value today appears two times or three times in my log column.
id log
1 today, yesterday, today, tomorrow, today
2 now, today, now
3 now, today, today
Select id from table if `today` appears three times in log column
The id:1 will be selected

This will do your job:
select * from table where ROUND (
(
LENGTH(log)
- LENGTH( REPLACE ( log, "today", "") )
) / LENGTH("today")
) >=3

Try this :
select * from yourtable a
inner join (
select max(id) as id,log,
sum(case when log = 'today' then 1 else 0 end) as c
from yourtable
group by log
) b on b.id = a.id and b.cnt = 3

Use the GROUP BY clause with HAVING
SELECT log
FROM tbl
GROUP BY log
HAVING COUNT(*) >= 2

Related

Fetch only 2 results, one for each different value of a concrete field

In a MYSQL table with those 5 fields: id, user_id, date, type, uid where type can be 1 or 2, I'm looking for a single query where I can fetch 2 results, one for type=1 and another one for type=2 based on date field.
Right now i have the following query which only gives me the last uid without taking care of the type field.
SELECT t.uid
FROM table AS t
WHERE t.user_id = 666
ORDER BY t.date
DESC LIMIT 1
Does anyone know how should modify this query so i can get the last uid for type=1 and the last one for type=2 based on date field? I would like to keep a a single query
Union all is probably the simplest method:
(select t.*
from t
where t.user_id = 666 and t.type = 1
order by date desc
limit 1
) union all
(select t.*
from t
where t.user_id = 666 and t.type = 2
order by date desc
limit 1
)
Finally i updated the query following this "paradigm":
http://dev.mysql.com/doc/refman/5.7/en/example-maximum-column-group-row.html
http://jan.kneschke.de/projects/mysql/groupwise-max/
This is how the query ended up:
SELECT s1.type, s1.uid
FROM t AS s1
LEFT JOIN t AS s2 ON s1.type = s2.type AND s1.date < s2.date
WHERE s2.date IS NULL;
Here's a visual example: http://hastebin.com/ibinidasuw.vhdl
Credits are for snoyes from #sql on Freenode. :)

SQL Group by day from timestamp with two tables

I have two tables with timestamp columns.
Table #1 contains clicks, timestamp and Table #2 contains userid, timestamp. I want the counts of clicks and users by date. for example
Date clicks_count users_count
2015-07-24 10 15
2015-07-24 04 06
I think these SQL useful to you.
select a.date1,clicks_count,users_count from
(select date(Table1.timestamp)as date1, count(clicks) as clicks_count
from Table1
group by date(Table1.timestamp)) as a
join
(
select date(Table2.timestamp) date2, count(userid) as users_count
from Table2
group by date(Table2.timestamp)) b on a.date1 = b.date2
Thank you.
select date(timestamp),
sum(is_click) as clicks,
sum(is_click = 0) as user_count
from
(
select timestamp, 1 as is_click from table1
union all
select timestamp, 0 from table2
) tmp
group by date(timestamp)
You can select the timestamps from both tables together and add a calculated column that indicates from which table the timestamp came from.
Then you take that subquery result and group by by the date and count the users and clicks.
sum(is_click = 0) counts how many time the timestamp came from the users table.

mysql : Get latest value and sum of values from previous hour

I would like to return a product together with its latest value and values from last hour.
I have a product-table :
id, name, type (and so on)...
I have a values-table :
id_prod, timestamp, value
Something like :
12:00:00 = 10
12:15:00 = 10
12:30:00 = 10
12:45:00 = 10
13:00:00 = 10
13:15:00 = 10
13:30:00 = 10
I would like a query that returns the latest value (13:30:00) together with the sum of values one hour back. This should return:
time = 13:30:00
latestread = 10
lasthour = 40
What I almost got working was:
SELECT *,
(SELECT value FROM values S WHERE id_prod=P.id
ORDER BY timestamp DESC LIMIT 1) as latestread,
(SELECT sum(value) FROM values WHERE id_prod=D.id and
date_created>SUBTIME(S.date_created,'01:00:00')) as trendread
FROM prod P ORDER BY name
But this fails with "Unknown column 'S.date_created' in 'where clause'"
Any suggestions?
If I understand correctly what you're trying to do, then You would have something like:
SELECT p.id, max(date_created), sum(value), mv.max_value
FROM product p
JOIN values v on p.id = v.product_id
JOIN (SELECT product_id, value as max_value
FROM values v2
WHERE date_created = (SELECT max(date_created) FROM values WHERE product_id=v2.product_id)) mv on product_id=p.id
WHERE date_created between DATE_SUB(now(), INTERVAL 1 HOUR)) and now()
GROUP BY p.id
ORDER BY p.id
Aleks G and mhasan gave solutions, but not the reason why this fails. The reason this fails is because the alias S is not known inside the subquery. Subqueries have no knowledge about the tables outside their scope.
You have missed providing alias for table Values in subquery below
SELECT *,
(SELECT value FROM values S WHERE id_prod=P.id
ORDER BY timestamp DESC LIMIT 1) as latestread,
(SELECT sum(value) FROM values S WHERE id_prod=P.id and
date_created>SUBTIME(S.date_created,'01:00:00')) as trendread
FROM prod P ORDER BY name
I think this is the query that you are trying to write:
SELECT p.*,
(SELECT v.value
FROM values v
WHERE v.id_prod = p.id
ORDER BY v.timestamp DESC
LIMIT 1
) as latestread,
(SELECT sum(v.value)
FROM values v
WHERE v.id_prod = p.id and
v.timestamp > SUBTIME(now(), '01:00:00')
) as trendread
FROM prod p
ORDER BY p.name;
This changes all the aliases to be abbreviations for the table name. It also fixes the expression for the last hour by using now() and gets rid of date_created which doesn't seem to be in either table based on the question. The query conveniently assumes that timestamp is a datetime. If it is a unix timestamp, then somewhat different time logic is necessary.
This should be reasonably efficient with an index on values(id_prod, timestamp, value).

SELECT * FROM table while condition=true?

i want to select something from table while one condition is true,
SELECT * FROM (SELECT * FROM`table1` `t1` ORDER BY t1.date) `t2` WHILE t2.id!=5
when while condition comes to false it stop selecting next rows.
Please help me, I have already search a lot and many similars in stackoverflow but I can't get it.
please don't tell me about where , i want solution in sql not in php or anything other
OK the real problem is here
SELECT *,(SELECT SUM(t2.amount) FROM (select * from transaction as t1 order by t1.date) `t2`) as total_per_transition FROM transaction
here i want to calculate total balance on each transaction
First find the first date where the condition fails, so where id=5:
SELECT date
FROM table1
WHERE id = 5
ORDER BY date
LIMIT 1
Then make the above a derived table (we call it lim) and join it to the original table to get all rows with previous dates: t.date < lim.date
SELECT t.*
FROM table1 AS t
JOIN
( SELECT date
FROM table1
WHERE id = 5
ORDER BY date
LIMIT 1
) AS lim
ON t.date < COALESCE(lim.date, '9999-12-31') ;
The COALESCE() is for the case when there are no rows at all with id=5 - and in that case we want all rows from the table.

Getting the newest record from a database Multiple queries

I have a mysql database with vehicles records. I need a fast query that will return the newest records of those records that were updated within the last 4 minutes. For example vehicle "A" may be updated several times a minute so it will appear many times within the last 4min. Same with vehicle B C etc. I need only the most recent entries for each vehicle within a 4 min window. I have tried like this
SELECT *
FROM yourtable AS a
WHERE a.ts =
(SELECT MAX(ts)
FROM yourtable AS b
WHERE b.ts > NOW() - INTERVAL 5 MINUTE
AND b.name = a.name)
but it takes too long to produce results >10seconds.
You don't need the self-join.
select max(ts), name from Table1
where ts > NOW() - INTERVAL 5 MINUTE
group by name
To get all the rows for the latest updates and not only the name and timestamp:
SELECT t.*
FROM
TableX AS t
JOIN
( SELECT name
, MAX(ts) AS maxts
FROM TableX
WHERE ts > NOW() - INTERVAL 4 MINUTE
GROUP BY name
) AS grp
ON grp.name = t.name
AND grp.maxts = t.ts
You'll need at least an index on the timestamp column for this query.