SQL query to group by day but with another condition - mysql

I have data something like this:
| visitor_id | time | my_flag |
| 1 | 01-01-2017 | 1 |
| 2 | 01-01-2017 | 1 |
| 1 | 01-02-2017 | 2 |
| 3 | 01-02-2017 | 2 |
etc...
I want to group all visitors in one day but based on a flag. The flag can have two values, 1 or 2. So I need something like
| 12 | 01-01-2017 | 1 |
| 10 | 01-01-2017 | 2 |
| 34 | 01-02-2017 | 1 |
I have
select v.visitor_id v.time, v.flag
from my_table as v
group by DAY(v.time) having flag=1;
But I am not able to figure out how to add multiple conditions (flag=1 and flag=2)? Any pointers?

try something like this
select v.visitor_id v.time, v.flag
from my_table as v
where v.flag in (1,2)
group by DAY(v.time), v.flag

SELECT v.time,
v.flag,
COUNT(v.visitor_id)
FROM my_table as v
GROUP BY v.time,
v.flag;`

Related

Retrieving data from the row containing the closest date to today with whereDate

I want to sort by price after filtering and grouping by date. However, because there are more than one relation, I cannot get the result I want.
The result I want is to get the price of the relation that is the closest to the end_date and sort it accordingly.
For this, the query, sql output, tables and demo page are as follows.
Thanks in advance ..
demo sqlfiddle
$query->join('tableB', 'tableA.id', '=', 'tableB.pro_id')
->select('tableA.*', 'tableB.start_date', 'tableB.end_date', 'tableB.old_daily')
->where(function($sq) {
$today = Carbon::now()->format('Y-m-d');
$sq->whereDate('end_date', '>=', $today);
})
->groupBy('tableA.id')
->orderBy('price', desc);
Query:
select `tableA`.*, `tableB`.`start_date`, `tableB`.`end_date`, `tableB`.`price`
from `tableA`
inner join `tableB` on `tableA`.`id` = `tableB`.`pro_id`
where (date(`end_date`) >= 2021-03-07)
group by `tableA`.`id`
order by `price` desc
tableA
| id | title |
|----|-------|
| 1 | pro1 |
| 2 | pro2 |
| 3 | pro3 |
tableB
| id | start_date | end_date | price | pro_id |
|----|------------|------------|-------|--------|
| 1 | 2021-06-01 | 2021-06-05 | 750 | 2 |
| 2 | 2021-05-01 | 2021-05-05 | 850 | 2 |
| 3 | 2021-04-01 | 2021-04-05 | 650 | 2 |
| 4 | 2021-06-01 | 2021-06-05 | 2750 | 1 |
| 5 | 2021-05-01 | 2021-05-05 | 2850 | 1 |
| 6 | 2021-04-01 | 2021-04-05 | 2650 | 1 |
| 7 | 2021-06-01 | 2021-06-05 | 1750 | 3 |
| 8 | 2021-05-01 | 2021-05-05 | 1850 | 3 |
| 9 | 2021-04-01 | 2021-04-05 | 1650 | 3 |
this query gives the result you want.
It would be a good choice to use "right join" in this step.
sqlfiddle
select `tableA`.*, `tableB`.`start_date`, `tableB`.`end_date`, `tableB`.`price`
from `tableA`
right join(
SELECT id, start_date, end_date, pro_id, price, DATEDIFF(`tableB`.`end_date`, '2021-03-07') diff
FROM `tableB`
GROUP BY id order by diff asc
) `tableB` on `tableA`.`id` = `tableB`.`pro_id`
where (date(`end_date`) >= '2021-03-07')
group by `tableA`.`id`
order by `price` desc
the closest to the end_date and sort it accordingly.
you should find the difference between the given date and end date then sort ascendingly.
ORDER BY DATEDIFF(end_date, '2021-03-07') ASC

How to select latest rank of item in mysql

I have two tables: coins and coin_history
coins table
|id | symbol | date |
+---+--------+----------+
|1 | BTC |01-02-2011|
|2 | ETH |21-02-2011|
|3 | XRP |08-01-2011|
|4 | BCH |25-01-2011|
coin_history table; rank of each coin on a date
|id | coin_id | rank | date |
+---+---------+--------+----------+
| 1 | 1 | 1 |01-02-2018|
| 2 | 1 | 1 |02-02-2018|
| 3 | 1 | 1 |04-02-2018|
| 4 | 2 | 2 |01-02-2018|
| 5 | 2 | 3 |02-02-2018|
| 6 | 2 | 2 |04-02-2018|
| 7 | 3 | 3 |01-02-2018|
| 8 | 3 | 2 |02-02-2018|
| 9 | 3 | 4 |04-02-2018|
|10 | 4 | 4 |01-02-2018|
|11 | 4 | 4 |02-02-2018|
|12 | 4 | 3 |04-02-2018|
I want to get each coin from coins ordered by latest rank from coin_history
something link this result:
|coin_id | symbol | rank |
+--------+--------+--------+
| 1 | BTC | 1 |
| 2 | ETH | 2 |
| 4 | BCH | 3 |
| 3 | XRP | 4 |
I've tried some queries but all of them result to this error
this is incompatible with sql_mode=only_full_group_by
In a Derived Table, get the Maximum value of date from the history for a particular coin.
Join this result-set with your main tables, to fetch only the row corresponding to recent date for a coin.
Eventually, use ORDER BY to get result in Ascending order for Rank.
Try:
SELECT
c.coin_id,
c.symbol,
ch.rank
FROM
coins AS c
JOIN
coin_history AS ch
ON ch.coin_id = c.coin_id
JOIN
(
SELECT coin_id,
MAX(date) AS max_date
FROM coin_history
GROUP BY coin_id
) AS dt
ON ch.coin_id = dt.coin_id AND
ch.date = dt.max_date
ORDER BY ch.rank
MySQL has a other more simple method but it is MySQL only, so don't use this when you need database portability in your code.
Using GROUP_CONCAT in combination with nested SUBSTRING_INDEX functions to get the first element/item can also be used to get a extra column which keeping the correct grouped information..
Note: SET SESSION group_concat_max_len = ##max_allowed_packet; is very important to use otherwise GROUP_CONCAT will only display 1024 bytes..
Query
SET SESSION group_concat_max_len = ##max_allowed_packet;
SELECT
coins.id AS coin_id
, coins.symbol
, CAST(
SUBSTRING_INDEX(
SUBSTRING_INDEX(
GROUP_CONCAT(coin_history.rank ORDER BY coin_history.date DESC)
, ','
, 1
)
, ','
, -1
) AS UNSIGNED) AS rank
FROM
coins
INNER JOIN
coin_history
ON
coins.id = coin_history.coin_id
GROUP BY
coins.id
, coins.symbol
ORDER BY
rank
Result
| coin_id | symbol | rank |
| ------- | ------ | ---- |
| 1 | BTC | 1 |
| 2 | ETH | 2 |
| 4 | BCH | 3 |
| 3 | XRP | 4 |
DB Fiddle demo
SELECT q.*from
(SELECT h.*, c.symbol
FROM `coin_history` AS h
JOIN coins AS c ON h.coin_id = c.id
ORDER BY h.date DESC
LIMIT 50) AS q
GROUP BY q.coin_id
ORDER BY q.rank ASC

MySQL query order by date desc, ignore other records

I have a MySql table with the following data:
| ID | House | Date |
| 1 | A | 2015-03-13 15:56:59 |
| 2 | A | 2015-03-11 12:19:45 |
| 3 | A | 2015-03-06 00:00:00 |
| 4 | B | 2015-03-13 16:07:21 |
| 5 | B | 2015-03-11 13:02:22 |
I'm trying to get the following results:
| ID | House | Date |
| 1 | A | 2015-03-13 15:56:59 |
| 4 | B | 2015-03-13 16:07:21 |
I've tried using subqueries and other types of things. Any ideas of what I could use?
Query:
select h1.id, h1.house, h1.date
from house h1 left join house h2
on h1.house = h2.house and h1.date < h2.date
where h2.date is null
This query makes no assumptions about the ordering of the data.
Demo: http://sqlfiddle.com/#!9/2da11/1
Assuming the table name is tableName
Select tbl.id, temp.house,
temp.datecol
from tableName tbl,
(
select max(tbl2.datecol),
tbl2.house
from tableName tbl2
group by tbl2.house
) temp
where tbl.house=temp.house
order by temp.datecol asc;
This can be done in a simpler way.
SELECT id, house, date FROM house WHERE date > '2015-03-13'

Select most recent MAX() and MIN() - WebSQL

i'm build an exercises web app and i'm working with two tables like this:
Table 1: weekly_stats
| id | code | type | date | time |
|----|--------------|--------------------|------------|----------|
| 1 | CC | 1 | 2015-02-04 | 19:15:00 |
| 2 | CC | 2 | 2015-01-28 | 19:15:00 |
| 3 | CPC | 1 | 2015-01-26 | 19:15:00 |
| 4 | CPC | 1 | 2015-01-25 | 19:15:00 |
| 5 | CP | 1 | 2015-01-24 | 19:15:00 |
| 6 | CC | 1 | 2015-01-23 | 19:15:00 |
| .. | ... | ... | ... | ... |
Table 2: global_stats
| id | exercise_number |correct | wrong |
|----|-----------------|--------|-----------|
| 1 | 138 | 1 | 0 |
| 2 | 246 | 1 | 0 |
| 3 | 988 | 1 | 10 |
| 4 | 13 | 5 | 0 |
| 5 | 5 | 4 | 7 |
| 6 | 5 | 4 | 7 |
| .. | ... | ... | ... |
What i would like is to get MAX(correct-wrong) and MIN(correct-wrong) and now i'm working with this query:
SELECT
exercise_number,
date,
time
FROM weekly_stats AS w JOIN global_stats AS g
ON w.id=g.id
WHERE correct - wrong = (SELECT MAX(correct - wrong) from global_stats)
UNION
SELECT
exercise_number,
date,
time
FROM weekly_stats AS w JOIN global_stats AS g
ON w.id=g.id
WHERE correct - wrong = (SELECT MIN(correct - wrong) from global_stats);
This query is working good, except for one thing: when "WHERE correct - wrong = (SELECT MIN(correct - wrong)[...]" selects more than one row, the row selected is the first but i would like to have returned the most recent (in other words: ordered by datetime(date, time)). Is it possible?
Thanks!
I think you can solve it like this:
SELECT * FROM (
SELECT
1 as sort_column,
exercise_number,
date,
time
FROM weekly_stats AS w JOIN global_stats AS g
ON w.id=g.id
WHERE correct - wrong = (SELECT MAX(correct - wrong) from global_stats)
ORDER BY date DESC, time DESC
LIMIT 1 ) as a
UNION
SELECT * FROM (
SELECT
2 as sort_column,
exercise_number,
date,
time
FROM weekly_stats AS w JOIN global_stats AS g
ON w.id=g.id
WHERE correct - wrong = (SELECT MIN(correct - wrong) from global_stats)
ORDER BY date DESC, time DESC
LIMIT 1) as b
ORDER BY sort_column;
Here is the documentation about how UNION works.

Order and group by date in Mysql

Hi all and thanks in advance.
I have a small problem which can not resolve, I have this table, and I want to sort by date and group it (but I only show 1 row per idCAT)
| id | idcat | name | date |
| 1 | 3 | xx | 2011-01-02 |
| 2 | 4 | xf | 2011-01-02 |
| 3 | 3 | cd | 2011-01-01 |
| 4 | 1 | cg | 2011-01-04 |
| 5 | 4 | ce | 2011-01-06 |
would like to stay that way, try in a way but I can not
| 2 | 4 | xf | 2011-01-02 |
| 3 | 3 | cd | 2011-01-01 |
| 4 | 1 | cg | 2011-01-04 |
Order by ID
Thank's a one friend the work.
SELECT id, idcat, name, date FROM (SELECT * FROM data ORDER BY idcat, date ) m GROUP BY idcat
I can't test conveniently atm, but try this:
SELECT FIRST(id), idcat, FIRST(name), FIRST(date) AS d FROM myTable GROUP BY idcat ORDER BY d;
Note the use of the FIRST calls to pick the first row in the table with any particular idcat.
If you are trying to get groupings by the idcat, then sorted by date:
select id, idcat, name, date from myTable group by idcat order by date;