1. ホーム
  2. mysql

[解決済み] MySQL JOINは最新行のみ?

2022-07-11 08:51:30

質問

customer_id、email、referenceを保存するcustomerテーブルを持っています。追加のテーブルcustomer_dataがあり、顧客に加えられた変更の履歴レコードを保存します。

顧客情報をテーブルに表示するために、2つのテーブルを結合する必要がありますが、customer_dataから最新の行だけをcustomerテーブルに結合する必要があります。

クエリはページ分割されるため、リミットとオフセットがあり、少し複雑になります。

MySQLでこれを行うにはどうしたらよいでしょうか。どこかにDISTINCTを入れたいような気がするのですが...。

今のところ、クエリはこんな感じです。

SELECT *, CONCAT(title,' ',forename,' ',surname) AS name
FROM customer c
INNER JOIN customer_data d on c.customer_id=d.customer_id
WHERE name LIKE '%Smith%' LIMIT 10, 20

さらに、このようにLIKEでCONCATが使えると考えていいのでしょうか?

(INNER JOINが間違ったタイプのJOINである可能性があることは承知しています。実は、JOINの違いについては、全くわかりません。これから調べてみようと思います!)

どのように解決するのですか?

以下を試してみてください。

SELECT    CONCAT(title, ' ', forename, ' ', surname) AS name
FROM      customer c
JOIN      (
              SELECT    MAX(id) max_id, customer_id 
              FROM      customer_data 
              GROUP BY  customer_id
          ) c_max ON (c_max.customer_id = c.customer_id)
JOIN      customer_data cd ON (cd.id = c_max.max_id)
WHERE     CONCAT(title, ' ', forename, ' ', surname) LIKE '%Smith%' 
LIMIT     10, 20;

なお JOIN は単なる同義語で INNER JOIN .

テストケースです。

CREATE TABLE customer (customer_id int);
CREATE TABLE customer_data (
   id int, 
   customer_id int, 
   title varchar(10),
   forename varchar(10),
   surname varchar(10)
);

INSERT INTO customer VALUES (1);
INSERT INTO customer VALUES (2);
INSERT INTO customer VALUES (3);

INSERT INTO customer_data VALUES (1, 1, 'Mr', 'Bobby', 'Smith');
INSERT INTO customer_data VALUES (2, 1, 'Mr', 'Bob', 'Smith');
INSERT INTO customer_data VALUES (3, 2, 'Mr', 'Jane', 'Green');
INSERT INTO customer_data VALUES (4, 2, 'Miss', 'Jane', 'Green');
INSERT INTO customer_data VALUES (5, 3, 'Dr', 'Jack', 'Black');

結果(クエリから LIMITWHERE ):

SELECT    CONCAT(title, ' ', forename, ' ', surname) AS name
FROM      customer c
JOIN      (
              SELECT    MAX(id) max_id, customer_id 
              FROM      customer_data 
              GROUP BY  customer_id
          ) c_max ON (c_max.customer_id = c.customer_id)
JOIN      customer_data cd ON (cd.id = c_max.max_id);

+-----------------+
| name            |
+-----------------+
| Mr Bob Smith    |
| Miss Jane Green |
| Dr Jack Black   |
+-----------------+
3 rows in set (0.00 sec)