简体   繁体   English

mysql左连接只从基本表的第一行

[英]mysql left join only first row from base table

I am hard thinking about how to LEFT JOIN data from one table to the BASE table .. but only for the FIRST row from base table ... is that even possible? 我很难考虑如何将一个表中的数据从LEFT JOIN移到BASE表中..但是仅对于基表中的FIRST行...这可能吗?

For example: 例如:

TABLE1 表格1

item_id  |  insert_datetime  |  value  
---------------------------------------
   2     | 1/1/2014 12:54:05 |   65
   2     | 1/1/2014 12:57:05 |   65
   3     | 8/7/2014 10:01:47 |   87
   3     | 9/8/2014 09:37:21 |   33
   3     | 9/8/2014 09:42:21 |   33
   4     | 2/9/2014 15:22:01 |   58

TABLE2 (left-joined by ID, date [not datetime], value) TABLE2 (由ID,日期[不是datetime],值左连接)

item_id  |   drop_datetime   |  value  
---------------------------------------
   2     | 1/1/2014 00:00:00 |   65
   3     | 9/8/2014 00:00:00 |   33

I need to do something like this: 我需要做这样的事情:

SELECT t1.item_id
, t1.insert_datetime as inserted
, t1.value as ins_value
##
, t2.drop_datetime as cancelled
, t2.value as cld_value
##
FROM table1 t1
##
LEFT JOIN table2 t2
ON t2.item_id = t1.item_id
AND date(t2.drop_datetime) = date(t1.insert_datetime)
AND t1.value = t2.value
##
WHERE 1=1

So it means I need to get which values were cancelled ... but in case of item_id = 2 there was following situation: 因此,这意味着我需要获取取消的值...但是在item_id = 2的情况下,会出现以下情况:

Item was shipped on 1/1/2014 12:54:05 (with value 65) ... it was cancelled (1st row in T2), because of wrong parameters and was reshipped 1/1/2014 12:57:05 with the same value 该商品于2014年1月1日12:54:05(值65)发货……由于参数错误而被取消(T2中的第一行),并于2014年1月1日12:57:05重新发货相同的值

What I get for item_id = 2 is: 我得到的item_id = 2是:

item_id  |     inserted      |  ins_value |  cancelled        |   cld_value
-----------------------------------------------------------------------------
   2     | 1/1/2014 12:54:05 |     65     | 1/1/2014 00:00:00 |      65
   2     | 1/1/2014 12:57:05 |     65     | 1/1/2014 00:00:00 |      65

But I NEED to get this: 但是我需要得到这个:

item_id  |     inserted      |  ins_value |  cancelled        |   cld_value
-----------------------------------------------------------------------------
   2     | 1/1/2014 12:54:05 |     65     | 1/1/2014 00:00:00 |      65
   2     | 1/1/2014 12:57:05 |     65     |                   |       

Because in reality, was only the first cancelled.. is is possible to get this result in MySQL? 因为实际上,只有第一个被取消的..是否有可能在MySQL中获得此结果?

NOTE: And an item also could be, unfortunatelly, cancelled for two or threetime in an hour 注意:不幸的是,一个项目也可以在一小时内取消两次或三次

                                   **EDIT 1**

If it helps ... all data are in one table with symptom of SHIP(1) or CANCLED(2) 如果有帮助...所有数据都在一个表中并带有SHIP(1)或CANCLED(2)的症状

SOURCE TABLE 来源表

id  |  item_id  |  insert_datetime  |  value  |  symptom  
-----------------------------------------------------------
1   |     2     | 1/1/2014 12:54:05 |   65    |     1
2   |     2     | 1/1/2014 00:00:00 |   65    |     2
3   |     2     | 1/1/2014 12:57:05 |   65    |     1
4   |     3     | 8/7/2014 10:01:47 |   87    |     1
5   |     3     | 9/8/2014 09:37:21 |   33    |     1
6   |     3     | 9/8/2014 00:00:00 |   33    |     2
7   |     3     | 9/8/2014 09:42:21 |   33    |     1
8   |     4     | 2/9/2014 15:22:01 |   58    |     1

will this help? 这会有所帮助吗?

                                   **POSSIBLE SOLUTION**

Ít seems that this works ok: 这似乎行得通:

SELECT t1.item_id
, t1.insert_datetime as inserted
, t1.value as ins_value
##
, t2.drop_datetime as cancelled
, t2.value as cld_value
##
FROM table1 t1
##
LEFT JOIN table2 t2
ON t2.item_id = t1.item_id
AND date(t2.drop_datetime) = date(t1.insert_datetime)
AND t1.value = t2.value
AND t1.id < t2.id   ## <- this should do the trick
##
WHERE 1=1

You can try this : 您可以尝试以下方法:

SQL Fiddle SQL小提琴

MySQL 5.5.32 Schema Setup : MySQL 5.5.32模式设置

CREATE TABLE Table1
    (`id` int, `item_id` int, `insert_datetime` datetime, `value` int, `symptom` int)
;

INSERT INTO Table1
    (`id`, `item_id`, `insert_datetime`, `value`, `symptom`)
VALUES
    (1, 2, '2014-01-01 12:54:05', 65, 1),
    (2, 2, '2014-01-01 00:00:00', 65, 2),
    (3, 2, '2014-01-01 12:57:05', 65, 1),
    (4, 3, '2014-07-08 10:01:47', 87, 1),
    (5, 3, '2014-08-09 09:37:21', 33, 1),
    (6, 3, '2014-08-09 00:00:00', 33, 2),
    (7, 3, '2014-08-09 09:42:21', 33, 1),
    (8, 3, '2014-08-09 00:00:00', 33, 2),
    (9, 3, '2014-08-09 09:48:29', 33, 1),
    (10, 3, '2014-09-02 15:22:01', 58, 1)
;

Query 1 : 查询1

SELECT DISTINCT t1.item_id
, t1.insert_datetime as inserted
, t1.value as ins_value
, ifnull(t2.insert_datetime,'') as cancelled
, ifnull(t2.value,'') as cld_value
FROM table1 t1
LEFT JOIN table1 t2
ON t2.item_id = t1.item_id
AND date(t2.insert_datetime) = date(t1.insert_datetime)
AND t1.value = t2.value
AND t1.id < t2.id 
AND t2.symptom = 2
WHERE t1.symptom = 1 

Results : 结果

| ITEM_ID |            INSERTED | INS_VALUE |           CANCELLED | CLD_VALUE |
|---------|---------------------|-----------|---------------------|-----------|
|       2 | 2014-01-01 12:54:05 |        65 | 2014-01-01 00:00:00 |        65 |
|       2 | 2014-01-01 12:57:05 |        65 |                     |           |
|       3 | 2014-07-08 10:01:47 |        87 |                     |           |
|       3 | 2014-08-09 09:37:21 |        33 | 2014-08-09 00:00:00 |        33 |
|       3 | 2014-08-09 09:42:21 |        33 | 2014-08-09 00:00:00 |        33 |
|       3 | 2014-08-09 09:48:29 |        33 |                     |           |
|       3 | 2014-09-02 15:22:01 |        58 |                     |           |

you can try this 你可以试试看

SET @rowNoIn:=0;
SET @RowNoCn:=0;
SET @itemIn='';
SET @itemCn='';

select i.*,c.*
from(
  SELECT 
    @rowNoIn:=CASE WHEN @itemIn=item_id THEN @rowNoIn+1 ELSE 1 END AS rowNo
    ,@itemIn:=item_id AS item_id
    ,insert_datetime
    ,value
  FROM table1
  ORDER BY item_id, insert_datetime
)i
left join (
  SELECT 
    @rowNoCn:=CASE WHEN @itemCn=item_id THEN @rowNoCn+1 ELSE 1 END AS rowNo
    ,@itemCn:=item_id AS item_id
    ,drop_datetime
    ,value
  FROM table2
  ORDER BY item_id, drop_datetime)c
on 
  i.item_id = c.item_id
  and i.rowNo = c.rowNo

sqlFiddle sqlFiddle

Note if there is an item cancellation it assumes the first item form table1 is to be cancelled (no matter what date) you can update the code to better suit your need, but hopefully it will lead you into a right direction. 请注意,如果有项目取消,则假定第一个项目表table1将被取消(无论什么日期),您可以更新代码以更好地满足您的需要,但希望它将引导您朝着正确的方向前进。 You should really consider adding ID to your table1 so you could reference the cancelled records explicitly. 您应该真正考虑将ID添加到table1中,以便可以显式引用已取消的记录。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM