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;
Related
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
I have a table full of duplicates. I'm trying to convert them so I can put a unique constraint across two fields (say, identifier1 and identifier2).
I would like to "collapse" those duplicates into single records, but of my records contain differing strings. I'd like to keep the last-touched in these circumstances (keeping the one from the highest ID and discarding the rest).
For example, I can aggregate the startDate below with MIN() -- but how do I only get the most recent location?
id | identifier1 | identifier2 | location | startDate
1 | alice | 0001 | ambridge | 2016-01-01
2 | bob | 1312 | brigadoon | 2017-01-01
3 | alice | 0001 | brigadoon | 2017-05-01
4 | bob | 9999 | brigadoon | 2015-01-01
5 | celeste | 1234 | cittegazze | 2011-01-01
id | identifier1 | identifier2 | location | startDate
6 | alice | 0001 | brigadoon | 2016-01-01
7 | bob | 1312 | brigadoon | 2017-01-01
8 | bob | 9999 | brigadoon | 2015-01-01
9 | celeste | 1234 | cittegazze | 2011-01-01
Try this:
select A.identifier1, A.identifier2, A.startDate, B.Location from (
select identifier1,
identifier2,
MIN(startDate) AS startDate
from TABLE_NAME
group by identifier1, identifier2
) AS A JOIN TABLE_NAME AS B
ON (A.identifier1 = B.identifier1 and A.identifier2 = B.identifier2 and A.startDate = B.startDate)
I think a more efficient query is simply:
select t.*
from t
where t.startDate = (select max(t2.startDate)
from t t2
where t2.identifier1 = t.identifier1 and t2.identifier2 = t.identifier2
);
The advantage of this approach is that it can take advantage of an index on (identifier1, identifier2, startDate).
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;`
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'
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.