Reputation: 5355
I am using mysql 5.7.32-1
and want to get the lastest row from my asset_profiles
table.
CREATE TABLE `companies` (
`id` bigint(20) UNSIGNED NOT NULL,
`symbol` varchar(191) NOT NULL,
`name` varchar(191) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL
);
CREATE TABLE `asset_profiles` (
`id` bigint(20) UNSIGNED NOT NULL,
`companies_id` int(11) NOT NULL DEFAULT '999999',
`persons_id` int(11) DEFAULT NULL,
`address1` varchar(191) DEFAULT NULL,
`address2` varchar(191) DEFAULT NULL,
`city` varchar(191) DEFAULT NULL,
`state` varchar(191) DEFAULT NULL,
`compensation` bigint(20) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL
);
ALTER TABLE `companies`
ADD PRIMARY KEY (`id`);
ALTER TABLE `asset_profiles`
ADD PRIMARY KEY (`id`);
INSERT INTO `companies` (`id`, `symbol`, `name`, `created_at`, `updated_at`) VALUES
(1, 'AAPL', 'Apple Inc.', '2020-10-06 19:00:05', '2021-01-31 14:00:34'),
(2, 'AMZN', 'Amazon.com Inc.', '2020-10-06 19:00:05', '2021-01-31 14:00:38'),
(3, 'IBM', 'International Business Machines Corporation', '2020-10-06 19:00:05', '2021-01-31 14:00:40');
INSERT INTO `asset_profiles` (`id`, `companies_id`, `persons_id`, `address1`, `address2`, `city`, `state`, `compensation`, `created_at`, `updated_at`) VALUES
(1, 1, NULL, 'One Apple Park Way', NULL, 'Cupertino', 'CA', 13213124, '2021-01-08 00:08:33', '2021-01-08 00:08:33'),
(2, 1, NULL, 'One Apple Park Way', NULL, 'Cupertino', 'CA', 3323124, '2021-01-04 00:08:33', '2021-01-04 00:08:33'),
(3, 1, NULL, 'One Apple Park Way', NULL, 'Cupertino', 'CA', 32131, '2020-12-04 00:08:33', '2020-12-04 00:08:33'),
(4, 1, NULL, 'One Apple Park Way', NULL, 'Cupertino', 'CA', 132323124, '2020-11-06 00:08:33', '2020-11-06 00:08:33'),
(5, 1, NULL, 'One Apple Park Way', NULL, 'Cupertino', 'CA', 13224, '2020-10-08 00:08:33', '2020-10-08 00:08:33'),
(6, 2, NULL, 'Amz', NULL, 'Cupertino', 'CA', 1333231, '2020-12-04 00:08:33', '2020-12-04 00:08:33'),
(7, 2, NULL, 'Amz', NULL, 'Cupertino', 'CA', 132323323124, '2020-11-06 00:08:33', '2020-11-06 00:08:33'),
(8, 3, NULL, 'One Apple Park Way', NULL, 'Cupertino', 'CA', 13224, '2020-10-08 00:08:33', '2020-10-08 00:08:33');
I tried:
SELECT
*
FROM
companies c
inner join (
select companies_id, max(created_at) as MaxDate
from asset_profiles a
group by a.companies_id
) tm on c.id = tm.companies_id and c.created_at = tm.MaxDate
I would like to get the following result:
| id | symbol | name | created_at | updated_at | id | companies_id | persons_id | address1 | address2 | city | state | compensation | created_at | updated_at |
| --- | ------ | ------------------------------------------- | ------------------- | ------------------- | --- | ------------ | ---------- | ------------------ | -------- | --------- | ----- | ------------ | ------------------- | ------------------- |
| 1 | AAPL | Apple Inc. | 2020-10-06 19:00:05 | 2021-01-31 14:00:34 | 1 | 1 | | One Apple Park Way | | Cupertino | CA | 13213124 | 2021-01-08 00:08:33 | 2021-01-08 00:08:33 |
| 2 | AMZN | Amazon.com Inc. | 2020-10-06 19:00:05 | 2021-01-31 14:00:38 | 6 | 2 | | Amz | | Cupertino | CA | 1333231 | 2020-12-04 00:08:33 | 2020-12-04 00:08:33 |
| 3 | IBM | International Business Machines Corporation | 2020-10-06 19:00:05 | 2021-01-31 14:00:40 | 8 | 3 | | One Apple Park Way | | Cupertino | CA | 13224 | 2020-10-08 00:08:33 | 2020-10-08 00:08:33 |
Find below my dbfiddle:
https://www.db-fiddle.com/f/oKeCF9gmpoQMdVm48NBXEQ/3
Any suggestions what I am doing wrong?
I appreciate your replies!
Upvotes: 1
Views: 36
Reputation: 35900
You can use corelated subquery using not exists
for it as follows:
select c.*, ap.*
from companies c
join asset_profiles ap on c.id = tm.companies_id
where not exists
(Select 1 from asset_profiles app
Where app.companies_id = ap.companies_id
And app.created_at > ap.created_at)
Upvotes: 1
Reputation: 1269773
You can use window functions in MySQL 8+:
select c.*, ap.*
from companies c join
(select ap.*,
row_number() over (partition by ap.companies_id order by ap.created_at desc) as seqnum
from asset_profiles ap
) ap
on c.id = tm.companies_id and seqnum = 1;
In earlier versions, I would suggest a correlated subquery:
select c.*, ap.*
from companies c join
asset_profiles ap
on c.id = tm.companies_id
where ap.created_at = (select max(ap2.created_at)
from asset_profiles ap2
where ap2.companies_id = ap.companies_id
);
For performance, I would recommend an index on asset_profiles(companies_id, created_at)
.
Upvotes: 1