Mysql查询优化

时间:2016-11-23 08:48:24

标签: mysql

你需要一些关于mysql查询的帮助

我的数据是这样的

Table base_status

| id | order_id | status | dt_added |
-------------------------------------
| 1  | 123      | xyz    | date3    |
| 2  | 123      | abc    | date2    |
| 3  | 123      | pqr    | date1    |

我正在努力获得输出

| order_id | xyz_date | abc_date | pqr_date |
-------------------------------------------
| 123      | date3    | date2    | date3    |

MySQL查询:

select BS.order_id, XYZ.dt_added AS xyz_date, 
       ABC.dt_added AS abc_date, PQR.dt_added AS pqr_date,
from base_status BS
LEFT JOIN base_status XYZ ON BS.order_id=TAS.order_id and TAS.status='xyz'
LEFT JOIN base_status ABC ON BS.order_id=TAS.order_id and TAS.status='abc'
LEFT JOIN base_status PQR ON BS.order_id=PQR.order_id and PQR.status='pqr'
....

我的问题:如何避免3个左连接。只有一次加入,还有什么可以做同样的事情吗?

5 个答案:

答案 0 :(得分:1)

不多次查询同一个表的最佳方法是使用GROUP_CONCAT对三个日期进行分组,并使用FIELD保留输入顺序:

SELECT order_id, GROUP_CONCAT(dt_added) AS "xyz_date,abc_date,pqr_date "
FROM base_status
WHERE status IN ('xyz', 'abc', 'pqr')
GROUP BY order_id
ORDER BY FIELD(status, 'xyz', 'abc', 'pqr')

当然,结果与您想要达到的结果略有不同:

| order_id | xyz_date,abc_date,pqr_date |
-----------------------------------------
| 123      | date3,date2,date1          |

答案 1 :(得分:1)

您可以使用group_concat(http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_group-concat

但是此解决方案需要进行后处理才能拆分值

SELECT order_id, GROUP_CONCAT(status), GROUP_CONCAT(dt_added) FROM     base_status GROUP BY order_id

单元格看起来像pqr, abc, xyzdate1, date2, date2

然后您可以使用SUBSTRING_INDEX将其拆分

答案 2 :(得分:0)

试试这个

var myDate = new Date();  

/* hour is before noon */ 
if ( myDate.getHours() < 12 ) {
    document.write("Good Morning!"); 
}

/* Hour is from noon to 5pm (actually to 5:59 pm) */
else if ( myDate.getHours() >= 12 && myDate.getHours() <= 17 ) {
    document.write("Good Afternoon!");
}

/* the hour is after 5pm, so it is between 6pm and midnight */
else if ( myDate.getHours() > 17 && myDate.getHours() <= 24 ) { 
    document.write("Good Evening!"); 
}

/* the hour is not between 0 and 24, so something is wrong */
else {
    document.write("I'm not sure what time it is!"); 
} 

获得这样的输出

SELECT 
    order_id, GROUP_CONCAT(status), GROUP_CONCAT(dt_added)
FROM
    base_status
GROUP BY
    order_id

答案 3 :(得分:0)

如果您有超过3个日期,可以使用动态数据透视

SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'MAX(case when dt_added = ''',
      dt_added ,
      ''' then dt_added  end) AS ',
      CONCAT(status,'_','date')
    )
  ) INTO @sql
from base_status;

SET @sql = CONCAT('SELECT order_id, ', @sql, ' from base_status
group by order_id');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

FIDDLE

答案 4 :(得分:0)

您可以使用与IF语句结合的聚合函数来恢复指定的列: -

SELECT order_id,
        MAX(IF(status = 'xyz', dt_added, NULL)) AS xyz_date,
        MAX(IF(status = 'abc', dt_added, NULL)) AS abc_date,
        MAX(IF(status = 'pqr', dt_added, NULL)) AS pqr_date
FROM base_status 
GROUP BY order_id

但是我怀疑如果正确编入索引,3表连接应该可以正常运行。