HiveBrain v1.2.0
Get Started
← Back to all entries
patternsqlMinor

MySQL LIMIT within JOIN

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
withinlimitmysqljoin

Problem

I have an 1:m association.

symbols table has many rows in company_key_statistics table. company_key_statistics has column createdAt which is timestamp indicating when row has been created.
I need to join latest symbols with company_key_statistics, but I need only latest company_key_statistics.
For example I need to get ORCL and MSFT symbols and only their latest company_key_statistics.

So far I have tried this.

SELECT `symbols`.`id`, 
       `symbols`.`symbol`, 
       `statistics`.
       `marketCapitalization` 
FROM   `symbols` 
       LEFT JOIN (SELECT `s`.`companyId`, 
                         `s`.`marketCapitalization` 
                  FROM   `company_key_statistics` AS `s`
                  WHERE  `s`.`companyId` = `symbols`.`id` 
                  ORDER by `createdAt` 
                  DESC LIMIT 1) AS `statistics` 
ON     `symbols`.`id` = `statistics`.`companyId` 
WHERE  `symbols`.`symbol` IN ('ORCL', 'SNAP');


But unfortunately I found that I can't use columns from parent query in JOIN subqueries.

How can I achieve to this?

Solution

For a correlated subquery you should use a CROSS APPLY, unfortunately MySql doesn't allow it, but you can simulate it on this way:

SELECT     `symbols`.`id`, 
           `symbols`.`symbol`, 
           `statistics`.
           `marketCapitalization`,
           `s`.`companyId`,
           `s`.`marketCapitalization`  
FROM       `symbols` 
INNER JOIN `company_key_statistics` `s`
ON         `s`.`pk` = (SELECT `pk`          -- the PK of company_key_statistics
                       FROM   `company_key_statistics`
                       WHERE  `companyId` = `symbols`.`id` 
                       ORDER by `createdAt` 
                       DESC LIMIT 1) 
WHERE  `symbols`.`symbol` IN ('ORCL', 'SNAP');


You can find some example on SO.

Code Snippets

SELECT     `symbols`.`id`, 
           `symbols`.`symbol`, 
           `statistics`.
           `marketCapitalization`,
           `s`.`companyId`,
           `s`.`marketCapitalization`  
FROM       `symbols` 
INNER JOIN `company_key_statistics` `s`
ON         `s`.`pk` = (SELECT `pk`          -- the PK of company_key_statistics
                       FROM   `company_key_statistics`
                       WHERE  `companyId` = `symbols`.`id` 
                       ORDER by `createdAt` 
                       DESC LIMIT 1) 
WHERE  `symbols`.`symbol` IN ('ORCL', 'SNAP');

Context

StackExchange Database Administrators Q#170756, answer score: 4

Revisions (0)

No revisions yet.