LoginSignup
2
0

概要

SQLにargmaxargminは無いです。

なのでmaxSELECTするサブクエリとINNER JOINすることによってがんばります。

argmaxargminってなぁに

argmaxというのは、何か値を最大にするものを得るときに使うものです。
maxは最大でいくつになるかを得るときに使う点で異なります。
逆にargminというのは、何か値を最小にするものを得るときに使うものです。
これもminは最小でいくつになるかを得るときに使う点で異なります。

たとえば、記事がたくさんあったとき、「いいねの一番多い記事」はargmaxですが、その「一番多くついたいいねの数」はmaxです。

やってみる

今回は記事の著者ごとに一番いいねの多い記事をSELECTしようと思います。

面倒なのでSQLite3で試してみます。

お試し用データ
BEGIN EXCLUSIVE TRANSACTION;
CREATE TABLE IF NOT EXISTS `articles` (`id` INTEGER PRIMARY KEY AUTOINCREMENT,`author_id` INTEGER NOT NULL,`likes` INTEGER DEFAULT 0);
INSERT INTO `articles` (`author_id`,`likes`) VALUES (1,120);
INSERT INTO `articles` (`author_id`,`likes`) VALUES (1,120);
INSERT INTO `articles` (`author_id`,`likes`) VALUES (1,100);
INSERT INTO `articles` (`author_id`,`likes`) VALUES (2,100);
INSERT INTO `articles` (`author_id`,`likes`) VALUES (2,80);
INSERT INTO `articles` (`author_id`,`likes`) VALUES (2,80);
INSERT INTO `articles` (`author_id`,`likes`) VALUES (3,100);
INSERT INTO `articles` (`author_id`,`likes`) VALUES (4,120);
COMMIT;

ふつうに全部SELECTするとこんな感じです。

id  author_id  likes
--  ---------  -----
1   1          120  
2   1          120  
3   1          100  
4   2          100  
5   2          80   
6   2          80   
7   3          100  
8   4          120  

今回の結論です。

SELECT `a`.* FROM `articles` AS `a` INNER JOIN (
    SELECT `author_id`,max(`likes`) AS `likes` FROM `articles` GROUP BY `author_id`
) AS `b` ON `a`.`author_id`=`b`.`author_id` WHERE `a`.`likes`=`b`.`likes`;

では試してみます。

id  author_id  likes
--  ---------  -----
1   1          120  
2   1          120  
4   2          100  
7   3          100  
8   4          120  

ちゃんとauthor_idごとにlikesが最大のものがすべて得られましたしました🎉
author_id=1のものもちゃんと2つあります🎉

結論

サブクエリでmaxGROUP BYして、それとINNER JOINするだけでした。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0