1

私は2つのテーブルを持っています:

mysql> select * from orders;
+------+---------------------+------------+---------+
| id   | created_at          | foreign_id | data    |
+------+---------------------+------------+---------+
|    1 | 2010-10-10 10:10:10 |          3 | order 1 |
|    4 | 2010-10-10 00:00:00 |          6 | order 4 |
|    5 | 2010-10-10 00:00:00 |          7 | order 5 |
+------+---------------------+------------+---------+

mysql> select * from activities;
+------+---------------------+------------+------+
| id   | created_at          | foreign_id | verb |
+------+---------------------+------------+------+
|    1 | 2010-10-10 10:10:10 |          3 | get  |
|    2 | 2010-10-10 10:10:15 |          3 | set  |
|    3 | 2010-10-10 10:10:20 |          3 | put  |
|    4 | 2010-10-10 00:00:00 |          6 | get  |
|    5 | 2010-10-11 00:00:00 |          6 | set  |
|    6 | 2010-10-12 00:00:00 |          6 | put  |
+------+---------------------+------------+------+

ここで、列に参加activitiesする必要があります。最小限の注文ごとに 1 つのアクティビティ (存在する場合) のみを選択します。たとえば、オーダーと活動はほぼ同時に作成されました。ordersforeign_idABS(TIMESTAMPDIFF(SECOND, orders.created_at, activities.created_at))

+----------+---------+---------------------+-------------+------+---------------------+
| order_id | data    | order_created_at    | activity_id | verb | activity_created_at |
+----------+---------+---------------------+-------------+------+---------------------+
|        1 | order 1 | 2010-10-10 10:10:10 |           1 | get  | 2010-10-10 10:10:10 |
|        4 | order 4 | 2010-10-10 00:00:00 |           4 | get  | 2010-10-10 00:00:00 |
|        5 | order 5 | 2010-10-10 00:00:00 |        NULL | NULL | NULL                |
+----------+---------+---------------------+-------------+------+---------------------+

次のクエリは、目的の行を含む一連の行を生成します。GROUP BYステートメントが含まれている場合、activities結合される行を制御することはできません。

SELECT o.id AS order_id
     , o.data AS data
     , o.created_at AS order_created_at
     , a.id AS activity_id
     , a.verb AS verb
     , a.created_at AS activity_created_at 
FROM orders AS o 
LEFT JOIN activities AS a ON a.foreign_id = o.foreign_id;

そのようなクエリを書くことは可能ですか? このセクションはより大きなレポート クエリの一部であるため、理想的には group by の使用を避けたいと思います。

4

1 に答える 1

1

両方のテーブルが謎の外部キーを参照しているため、以下のクエリでエラーが発生する可能性がありますが、目的に合わせて適応できる原則が得られる可能性があります...

DROP TABLE IF EXISTS orders;

CREATE TABLE orders
(id INT NOT NULL PRIMARY KEY
,created_at DATETIME NOT NULL
,foreign_id INT NOT NULL
,data    VARCHAR(20) NOT NULL
);

INSERT INTO orders VALUES
(1 ,'2010-10-10 10:10:10',3 ,'order 1'),
(4 ,'2010-10-10 00:00:00',6 ,'order 4'),
(5 ,'2010-10-10 00:00:00',7 ,'order 5');

DROP TABLE IF EXISTS activities;

CREATE TABLE activities
(id   INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,created_at          DATETIME NOT NULL
,foreign_id INT NOT NULL
,verb VARCHAR(20) NOT NULL
);

INSERT INTO activities VALUES
(1,'2010-10-10 10:10:10',3,'get'),
(2,'2010-10-10 10:10:15',3,'set'),
(3,'2010-10-10 10:10:20',3,'put'),
(4,'2010-10-10 00:00:00',6,'get'),
(5,'2010-10-11 00:00:00',6,'set'),
(6,'2010-10-12 00:00:00',6,'put');

SELECT o.id order_id
     , o.data
     , o.created_at order_created_at    
     , a.id activity_id 
     , a.verb 
     , a.created_at activity_created_at 
  FROM activities a 
  JOIN orders o 
    ON o.foreign_id = a.foreign_id 
  JOIN 
     ( SELECT a.foreign_id
            , MIN(ABS(TIMEDIFF(a.created_at,o.created_at))) x 
         FROM activities a 
         JOIN orders o 
           ON o.foreign_id = a.foreign_id 
        GROUP 
           BY a.foreign_id
     ) m 
    ON m.foreign_id = a.foreign_id
   AND m.x = ABS(TIMEDIFF(a.created_at,o.created_at))
 UNION DISTINCT
SELECT o.id 
     , o.data
     , o.created_at
     , a.id
     , a.verb
     , a.created_at
  FROM orders o
  LEFT
  JOIN activities a
    ON a.foreign_id = o.foreign_id 
 WHERE a.foreign_id IS NULL;
;

+----------+---------+---------------------+-------------+------+---------------------+
| order_id | data    | order_created_at    | activity_id | verb | activity_created_at |
+----------+---------+---------------------+-------------+------+---------------------+
|        1 | order 1 | 2010-10-10 10:10:10 |           1 | get  | 2010-10-10 10:10:10 |
|        4 | order 4 | 2010-10-10 00:00:00 |           4 | get  | 2010-10-10 00:00:00 |
|        5 | order 5 | 2010-10-10 00:00:00 |        NULL | NULL | NULL                |
+----------+---------+---------------------+-------------+------+---------------------+
于 2013-03-11T15:13:16.797 に答える