I have this query:
SELECT t1.* FROM table t1
JOIN
(
SELECT MIN(orig_id) min_orig_id, MAX(orig_id) max_orig_id
FROM table
GROUP BY left(datetime,4), mid(datetime,5,2),
mid(datetime,7,2), mid(datetime,10,2), mid(datetime,13,2)
) t2
ON t1.orig_id = t2.min_orig_id OR t1.orig_id = t2.max_orig_id;
It groups records by first & last record in each minute.
Now I want to group by first & last record in each 3 minutes.
Any idea?
Thanks
This might be what you're looking for
SELECT t1.* FROM table t1
JOIN
(
SELECT MIN(orig_id) min_orig_id, MAX(orig_id) max_orig_id
FROM table
GROUP BY concat(left(datetime,4), mid(datetime,5,2),
mid(datetime,7,2), mid(datetime,10,2),(cast mid(datetime,13,2) as integer)/3)
) t2
ON t1.orig_id = t2.min_orig_id OR t1.orig_id = t2.max_orig_id;
If datetime is a timestamp/datetime data type and not a string
SELECT t1.* FROM table t1
JOIN
(
SELECT MIN(orig_id) min_orig_id, MAX(orig_id) max_orig_id
FROM table
GROUP BY UNIX_TIMESTAMP(datetime)/3
) t2
ON t1.orig_id = t2.min_orig_id OR t1.orig_id = t2.max_orig_id;
is much cleaner
Related
Consider the following table:
As shown in image, I want to return all the data from only first distinct id. How can I achieve that in MySQL ?
You can filter with a subquery. Assuming that by first you mean the row with the earlier start_time, that would be:
select t.*
from mytable t
where t.start_time = (
select min(t1.start_time) from mytable t1 where t1.call_unique_id = t.call_unique_id
)
from your_table t1
join
(
select min(call_unique_id) as id
from your_table
group by start_time
) t2 on t1.id = t2.id
group by should also do the job. so try
select * from your_table group by call_unique_id
So my table has:
column1, column2, column3 & datetime
SELECT * FROM mytable WHERE column1 = :column1
CONCAT column1 & column2 (column1NRcolumn2) to get a string to search for duplicates.
SELECT 1 column1_column2 WHERE datetime is highest
What i want is to combine two cells to create a new temponary column. (column1NRcolumn2)
Then i want to look for duplicates and then select the latest column1NRcolum2 WHERE datetime is highest/latest
How can i manage this?
You could use a subquery for concatenated columns having count > 1 and join to your table for max datetime
select t.my_concat, max(m.datetime)
from mytable m
inner join (
SELECT concat(column1,column2) my_concat
FROM mytable
group by concat(column1,column2)
having count(*)>1
) t
group by t.my_concat
and if you need thre related mytable columns you need a join on the max datetime
select m2.*
from mytable m2
inner join
(
select t.my_concat, max(m.datetime) max_datetime
from mytable m
inner join (
SELECT concat(column1,column2) my_concat
FROM mytable
group by concat(column1,column2)
having count(*)>1
) t
group by t.my_concat
) t2 on t2.my_concat = m2. concat(column1,column2)
and t.max_datetime = m2.datetime
I read few articles about this: Select max date, then max time This one seems most helpful but I do not see way to implement it.
There is five tables. I join them. I need to select only one row with highest date and highest time from first table and same from second table and join the rest on some other value. With the code I wrote I get multiple rows. It seems time selection is not right.
It might be done with subquery in subquery. I've tried something like this:
SELECT * from table1
INNER JOIN table2 ON table1.date = table2.date AND table1.gm = table2.gm
INNER JOIN table3 ON table2.gm = table3.gm ...
WHERE table3.date = :date AND table4.date = :date ...
AND table1.date IN(
SELECT MAX(table1.date) FROM table1 WHERE table1.time IN(
SELECT MAX(table1.time) FROM table1
)
)
AND table2.date IN(
SELECT MAX(table2.date) FROM table1 WHERE table2.time IN(
SELECT MAX(table2.time) FROM table2 )
)
ORDER BY table1.id
Question is:
How to get single row after joining all of this where date is highest and time is highest on that date?
Thanks!
EDIT: I am sorry for this. I forgot to say that I need max time of max date related with specific value from tables(gm columns). So that is one row(in example I gave it is table1.gm and table2.gm ... ) for each one of that .gm values which are same in every table, not just one row all together. Solutions Nick and Salim provided works but I did not solved problem.
EDIT: SOLVED! after implementing solutions by Nick I just neded to add GROUP BY cntrs_reper.gm_company_no, cntrs_reper.date.
And that's it. For every row in one table enties with highest date and time from others!! Thanks to all.
EDIT. If this can help this is full query:
SELECT cntrs_gm.gm_company_no AS company_c_g,
bns_gms.ded_bns AS ded_bns_gms,
bns_gms.no_ded_bns AS no_ded_bns_gms,
bns_gms.wag_ded_bns AS wag_ded_bns_gms,
cntrs_gm.cur_credit AS cur_credit_c_g,
cntrs_gm.cdrop AS cdrop_c_g,
cntrs_gm.total_jp AS total_jp_c_g,
cntrs_gm.games AS games_c_g,
cntrs_gm.wgames AS wgames_c_g,
cntrs_gm.doors AS doors_c_g,
cntrs_gm.power AS power_c_g,
cntrs_gm.total_in AS total_in_c_g,
cntrs_gm.total_out AS total_out_c_g,
cntrs_gm.total_acc AS total_acc_c_g,
cntrs_gm.total_bet AS total_bet_c_g,
cntrs_gm.total_win AS total_win_c_g,
cntrs_gm.total_bonus AS total_bonus_c_g,
cntrs_gm.date AS date_c_g,
cntrs_reper.gm_company_no AS company_reper,
bns_reper.ded_bns AS ded_bns_reper,
bns_reper.no_ded_bns AS no_ded_bns_reper,
bns_reper.wag_ded_bns AS wag_ded_bns_reper,
cntrs_reper.cur_credit AS cur_credit_reper,
cntrs_reper.cdrop AS cdrop_reper,
cntrs_reper.total_jp AS total_jp_reper,
cntrs_reper.games AS games_reper,
cntrs_reper.wgames AS wgames_reper,
cntrs_reper.doors AS doors_reper,
cntrs_reper.power AS power_reper,
cntrs_reper.total_in AS total_in_reper,
cntrs_reper.total_out AS total_out_reper,
cntrs_reper.total_acc AS total_acc_reper,
cntrs_reper.total_bet AS total_bet_reper,
cntrs_reper.total_win AS total_win_reper,
cntrs_reper.total_bonus AS total_bonus_reper,
cntrs_reper.date AS date_reper,
cntrs_reper.time AS time_reper,
bns_reper.time AS time_c_g,
gms_cfg.gm_no AS machine_id,
gms_cfg.denom_cin AS machine_cin
FROM bns_gms
INNER JOIN cntrs_gm
ON bns_gms.gm_company_no = cntrs_gm.gm_company_no AND bns_gms.date = cntrs_gm.date
INNER JOIN bns_reper
ON cntrs_gm.gm_company_no = bns_reper.gm_company_no
INNER JOIN cntrs_reper
ON bns_reper.gm_company_no = cntrs_reper.gm_company_no AND bns_reper.date = cntrs_reper.date
INNER JOIN gms_cfg
ON cntrs_reper.gm_company_no = gms_cfg.gm_no
WHERE bns_reper.date IN(
SELECT MAX(DATE(bns_reper.date)) FROM bns_reper WHERE bns_reper.time IN(
SELECT MAX(TIME(bns_reper.time)) FROM bns_reper
)
)
AND cntrs_reper.date IN(
SELECT MAX(DATE(cntrs_reper.date)) FROM cntrs_reper WHERE cntrs_reper.time IN(
SELECT MAX(TIME(cntrs_reper.time)) FROM cntrs_reper
)
)
ORDER BY cntrs_gm.gm_company_no
DB example
bns_gms
bns_reper
cntrs_gm
cntrs_reper
gms_cfg
The problem with your current query is that it will select all rows where table1.date is the latest date on which the highest time occurs, which may well be more than one e.g. for data such as
id date time
1 2018-03-30 18:40
2 2018-03-31 12:20
3 2018-03-31 19:20
Your WHERE clause:
table1.date IN(
SELECT MAX(table1.date) FROM table1 WHERE table1.time IN(
SELECT MAX(table1.time) FROM table1
)
will select rows with id=2 and id=3 as they both have date = '2018-03-31' which is when the maximum time occurs.
What you want to do is select the row which has the latest time on the latest date, for which you could use
table1.date = (SELECT MAX(date) FROM table1) AND
table1.time = (SELECT MAX(time) FROM table1 WHERE date = (SELECT(MAX(date) FROM table1))
By using aliasing, that can be simplified (since we already know table1.date = MAX(date) FROM table1) to
table1.date = (SELECT MAX(date) FROM table1) AND
table1.time = (SELECT MAX(time) FROM table1 AS t1 WHERE t1.date = table1.date)
I don't have MySQL but here is the general idea you can use. I don't have enough points to write a comment so I am responding as a reply. Essentially make a subquery/inline view for each table to select max of a column, then join those subqueries/inline views together.
Here is Oracle syntax. You can convert it to ANSI syntax.
select table1.column1, table2.column2,table3.column3
from
(select id1, max(column1) as column1 from table1 group by id1) as table1
(select id2, max(column2) as column2 from table2 group by id2) as table2
(select id3, max(column3) as column3 from table3 group by id3) as table3
where
table1.id1 = table2.id2
and table1.id1 = table3.id3
;
the case is that I need to select a field distinct from table1 (no duplicates) and use the result as a key to select from another table2. And I need this to be in one query. Is this possible?!
table1: hID, hName, hLocation
table2: hID, hFrom, hTo, hRate, hRoomType, hMeals
I want to correct version of this query:
SELECT
*
FROM
table1
JOIN (
DISTINCT
hID
FROM
table2
WHERE
hRoomType = Double Room
ON table1.hID = table2.hID)
expected result: all hotels that offer Double Room thanks much –
thanks for help!
Your question is quite vague and confusing. Is this what you are looking for:
SELECT hID, name, location
FROM table2
INNER JOIN table1
ON table1.hID = table2.hID
GROUP BY table2.hID;
Here is a skeleton to achieve this:
SELECT
* -- Don't forget to list the requested fields instead of using `*`!
FROM (
-- This is the distinct list from table1
SELECT DISTINCT
id
FROM
table1 T1
) DT1
INNER JOIN table2 T2
ON T1.id = T2.reference_to_t1_id
Another solution if you don't want to retrieve any columns from table1:
SELECT
* -- Don't forget to list the requested fields instead of using `*`!
FROM
table2 T2
WHERE
-- Sais that get all record from table2 where this condition matches
-- at least one record
EXISTS (
SELECT 1 FROM table1 T1 WHERE T1.id = T2.reference_to_t1_id
)
For your tables and question
SELECT
hID, hName, hLocation
FROM
table1 T1
WHERE
EXISTS (
SELECT 1 FROM
table2 T2
WHERE
T1.hID = T2.hID
AND T.hRoomType = 'Double' -- Assuming that this is the definition of double rooms
)
Is it possible to get 1 result where I require data from 3 tables.
First table: I will need to grab all the fields (1 row found by a primary key)
Second table: I will need to grab the field 'username' (connected to first table by 'master_id')
Third table: I will need to grab the latest added row with the associated master_id key (table has 'date', 'master_id', 'previous_name').
select top 1 first.*, second.username, third.*
from first
inner join second on first.id = second.master_id
inner join third on first.id = third.master_id
order by
third.date desc
As always there are dozens of ways to skin a cat, I'm not sure if this is optimized as the subquery methods, but it should work.
You can join the three tables together. Then, you can use a "filter" join to keep only the latest Table3 row:
select *
from Table1 t1
join Table2 t2
on t2.master_id = t1.master_id
join Table3 t3
on t3.master_id = t1.master_id
join (
select master_id
, max(date) as max_date
from Table3
group by
master_id
) as filter
on t3.master_id = filter.master_id
and t3.date = filter.max_date
You'll need a correlated subquery for that third table.
SELECT t1.*, username, date, previous_name
FROM FirstTable t1
INNER JOIN SecondTable t2 ON t1.master_id=t2.master_id
INNER JOIN
(SELECT master_id, date, previous_name
FROM ThirdTable AS t3_1
WHERE date = (
SELECT MAX(date)
FROM ThirdTable AS t3_2
WHERE t3_2.master_id=t3_1.master_id)) q1 ON q1.master_id=t1.master_id;
NOTE: Untested.