web-dev-qa-db-ja.com

JOIN内のMySQL LIMIT

1:mの協会があります。

symbolsテーブルのcompany_key_statisticsテーブルには多くの行があります。 company_key_statisticsには列createdAtがあります。これは、行がいつ作成されたかを示すタイムスタンプです。最新のsymbolscompany_key_statisticsを結合する必要がありますが、最新のcompany_key_statisticsのみが必要です。たとえば、ORCLMSFTsymbolsと最新のcompany_key_statisticsのみを取得する必要があります。

これまで私はこれを試しました。

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');

しかし、残念ながら、JOINサブクエリでは親クエリの列を使用できないことがわかりました。

これをどのように達成できますか?

3
Aren Hovsepyan

これを試して:

SELECT sym.id, sym.symbol, s.marketCapitalization 
  FROM symbols AS sym 
  INNER JOIN company_key_statistics AS s 
     ON sym.id = s.companyId 
  INNER JOIN (SELECT companyId, MAX(createdAt) AS createdAt 
                FROM company_key_statistics 
                GROUP BY companyId) AS smax 
     ON smax.companyId = s.companyId AND smax.createdAt = s.createdAt 
  WHERE sym.symbol IN ('ORCL','SNAP');

あなたの投稿した例はLEFT JOIN、多分あなたはあなたの答えに時価総額のデータのない会社も欲しがります。この場合、次のように副選択をネストする必要があります。

SELECT sym.id, sym.symbol, s.marketCapitalization 
  FROM symbols AS sym 
  LEFT JOIN (SELECT * 
               FROM company_key_statistics
               INNER JOIN (SELECT companyId, MAX(createdAt) AS createdAt 
                             FROM company_key_statistics 
                             GROUP BY companyId) AS smax 
               USING (companyId, createdAt)) AS s 
    ON sym.id = s.companyId 
 WHERE sym.symbol IN ('ORCL','SNAP');

ここで取り上げている一般的な問題はgroupwise maximumと呼ばれ、多くのSOとDBA.SEの回答が対処します。たとえば これ を確認します。

2
Dario

相関サブクエリの場合、CROSS APPLYを使用する必要がありますが、残念ながらMySqlでは許可されていませんが、次の方法でシミュレートできます。

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');

[〜#〜] so [〜#〜] で例を見つけることができます。

3
McNets