简体   繁体   中英

mySql query group by with order by date not working

I have two tables like this and I want latest data by date

tbl_fruit_info
+-----+--------+
| sId | sName  |
+-----+--------+
|   1 | Apple  |
|   2 | Banana |
|   3 | Orange |
+-----+--------+

tbl_fruit_data
+------------+----------+-------------+
|    date    | fruit_id | fruit_price |
+------------+----------+-------------+
| 2017-01-26 |        1 | 44.7        |
| 2017-01-27 |        1 | 51          |
| 2017-01-25 |        1 | 71.5        |
| 2017-01-21 |        2 | 44          |
| 2017-01-23 |        2 | 55          |
| 2017-01-24 |        2 | 71          |
+------------+----------+-------------+

I tried with this

                    SELECT tbl_fruit_info.*, tbl_fruit_data.*
                    FROM tbl_fruit_data 
                    LEFT JOIN 
                        tbl_fruit_info ON tbl_fruit_info.sId = tbl_fruit_data.fruit_id 
                    GROUP BY 
                        tbl_fruit_info.sId
                    ORDER BY 
                        max(tbl_fruit_data.date) DESC;

The Output I am looking for is like this:

+-----+--------+----------------------------+
| sId | sName  | date          |fruit_price | 
+-----+--------+----------------------------+
|   1 | Apple  | 2017-01-27    | 51         |
|   2 | Banana | 2017-01-24    | 71         |
|   3 | Orange | 0000-00-00    | 0          |
+-----+--------+----------------------------+

But I get this:

+-----+--------+----------------------------+
| sId | sName  | date          |fruit_price | 
+-----+--------+----------------------------+
|   1 | Apple  | 2017-01-26    | 44.7       |
|   2 | Banana | 2017-01-21    | 44         |
+-----+--------+----------------------------+

Any assistance would be greatly appreciated.

select * from tbl_fruit_data f
    left join tbl_fruit_info i ON i.sId = f.fruit_id 
where f.Date =
    (Select max(date) from tbl_fruit_data
     where fruit_id = f.fruit_id)
SELECT fi.*, fd.*
FROM tbl_fruit_data fd
  FULL OUTER JOIN tbl_fruit_info fi ON fi.sId = fd.fruit_id
WHERE fd.fruit_id IS NULL OR fd.date = (
  SELECT max(fd_inner.date)
  FROM tbl_fruit_data fd_inner
  WHERE fd_inner.fruit_id = fd.fruit_id
) 
ORDER BY fd.date DESC;

Update 2017-01-30: Incorporates rows in tbl_fruit_info that don't have a corresponding row in tbl_fruit_data, now.

Ok here goes.

**Get the latest prices on fruit, ADDED fruits not having a price

SELECT d1.date, d1.fruit_id, d1.fruit_price, i.sId, i.sName 
FROM tbl_fruit_info i
LEFT JOIN tbl_fruit_data d1
ON d1.fruit_id = i.sId
WHERE d1.date = (SELECT MAX(d2.date) 
                FROM tbl_fruit_data d2
                WHERE d2.fruit_id = d1.fruit_id
                 )
UNION
SELECT CAST('0001-01-01' AS datetime) date, i.sId fruit_id, 0 fruit_price, i.sId, i.sName
FROM tbl_fruit_info i
WHERE i.sId NOT IN (SELECT d2.fruit_id FROM tbl_fruit_data d2)

Sql fiddle for test on the same data provides in question:

http://sqlfiddle.com/#!9/872ed4/9

Used these definitions

CREATE TABLE tbl_fruit_info
    (`sId` int, `sName` varchar(6))
;

INSERT INTO tbl_fruit_info
    (`sId`, `sName`)
VALUES
    (1, 'Apple'),
    (2, 'Banana'),
    (3, 'Orange')
;


CREATE TABLE tbl_fruit_data
    (`date` datetime, `fruit_id` int, `fruit_price` int)
;

INSERT INTO tbl_fruit_data
    (`date`, `fruit_id`, `fruit_price`)
VALUES
    ('2017-01-26 00:00:00', 1, 44.7),
    ('2017-01-27 00:00:00', 1, 51),
    ('2017-01-25 00:00:00', 1, 71.5),
    ('2017-01-21 00:00:00', 2, 44),
    ('2017-01-23 00:00:00', 2, 55),
    ('2017-01-24 00:00:00', 2, 71)
;

Using dadde's fiddle (with some tweaks) - and assuming that the MySQL tag is correct...

CREATE TABLE tbl_fruit_info
    (`sId` int auto_increment PRIMARY KEY, `sName` varchar(6))
;

INSERT INTO tbl_fruit_info
    (`sId`, `sName`)
VALUES
    (1, 'Apple'),
    (2, 'Banana'),
    (3, 'Orange')
;


CREATE TABLE tbl_fruit_data
    (`date` datetime, `fruit_id` int, `fruit_price` int, primary key (fruit_id,date))
;

INSERT INTO tbl_fruit_data
    (`date`, `fruit_id`, `fruit_price`)
VALUES
    ('2017-01-26 00:00:00', 1, 44.7),
    ('2017-01-27 00:00:00', 1, 51),
    ('2017-01-25 00:00:00', 1, 71.5),
    ('2017-01-21 00:00:00', 2, 44),
    ('2017-01-23 00:00:00', 2, 55),
    ('2017-01-24 00:00:00', 2, 71)
;

SELECT a.sid
     , a.sname
     , COALESCE(b.date,'0000-00-00') date
     , COALESCE(b.fruit_price,0) fruit_price 
  FROM tbl_fruit_info a 
  LEFT 
  JOIN 
     ( SELECT x.* 
         FROM tbl_fruit_data x 
         JOIN 
            ( SELECT fruit_id, MAX(date) date 
         FROM tbl_fruit_data 
        GROUP 
           BY fruit_id
     ) y 
    ON y.fruit_id = x.fruit_id 
   AND y.date = x.date) b 
    ON b.fruit_id = a.sid;
+-----+--------+---------------------+-------------+
| sid | sname  | date                | fruit_price |
+-----+--------+---------------------+-------------+
|   1 | Apple  | 2017-01-27 00:00:00 |          51 |
|   2 | Banana | 2017-01-24 00:00:00 |          71 |
|   3 | Orange | 0000-00-00          |           0 |
+-----+--------+---------------------+-------------+
create table #t1
(id int,name varchar(100));


create table #t2(
[date] date,
id int,
price float)

insert into #t1
select 1,'Apple'
union
select 2,'Banana'

insert into #t2
select getdate()-3,1,33.2
union
select getdate()-2,1,30.5
union
select getdate()-4,1,23.4
union
select getdate()-3,2,21
union
select getdate()-2,2,35

Query

select q.name,t2.* from (
select  t1.id,t1.name,MAX(t2.date) as date from #t1 t1
inner join #t2 t2 on t1.id=t2.id
group by t1.id,t1.name
) as q inner join #t2 t2
on q.id=t2.id and t2.date=q.date

Edit: Fixed, replaced CTE with subquery, thanks dadde for pointing out CTE isn't supported in MySQL. CTE or Subquery does the same job here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM