隐式原始mysql查询转换为yii2查询2左连接子查询并求和全部

如何解决隐式原始mysql查询转换为yii2查询2左连接子查询并求和全部

我已经在mysql中创建了原始查询,但运行正常。我正在尝试将其转换为yii2查询,但我无法完成它,谁能帮我

原始查询:

SELECT
  ship.month_name,MIN(ship.average_value_percent) as minimum_container_utilization,MAX(ship.average_value_percent) as maximum_container_utilization,SUM(ship.average_value) / COUNT(ship.shipment) as volume,SUM(ship.average_weight) / COUNT(ship.shipment) as volume_kgs,SUM(ship.average_volume_cbm) / COUNT(ship.shipment) as volume_cbm,SUM(ship.average_value_percent) / COUNT(ship.shipment) as volume_percent
FROM
  (
    SELECT
      sh.JS_UniqueConsignRef as shipment,SUM(sp.volume) as average_volume_cbm,SUM(sp.volume) / SUM(sc.teu) AS average_value,SUM(sp.volume) / SUM(sc.capacity) AS average_value_percent,SUM(sp.weight) as average_weight,date_format(sh.JS_E_ARV,'%b') AS month_name,if(
        month(sh.JS_E_ARV) >= month(now()),month(sh.JS_E_ARV),month(sh.JS_E_ARV) + 12
      ) as months_order
    FROM
      ship_head sh
      JOIN (
        SELECT
          SUM(RC_TEU) teu,SUM(RC_Cubiccapacity) capacity,ship_head_id,JC_ContainerMode,JC_ContainerNum
        FROM
          ship_container
        GROUP BY
          ship_head_id,JC_ContainerNum,JC_ContainerMode
      ) sc ON sc.ship_head_id = sh.sh_id
      JOIN (
        SELECT
          SUM(JL_ActualVolume) volume,SUM(JL_ActualWeight) weight,JC_ContainerNum
        FROM
          ship_pack
        GROUP BY
          ship_head_id,JC_ContainerNum
      ) sp ON sp.ship_head_id = sh.sh_id
    WHERE
      sh.is_latest = 1
      AND sp.JC_ContainerNum = sc.JC_ContainerNum
      AND sc.JC_ContainerMode IN ('FCL','FTL')
      AND sh.JS_E_ARV < NOW() - INTERVAL 1 MONTH
      and sh.JS_E_ARV > Date_add(NOW() - INTERVAL 1 MONTH,interval - 12 month)
    GROUP BY
      sh.sh_id
  ) AS ship
GROUP BY
  ship.month_name,ship.months_order
ORDER BY
  ship.months_order

Yii2查询

$shipContainerQuery = ShipContainer::find()
    ->select(['SUM(RC_TEU) AS teu','SUM(RC_Cubiccapacity) AS capacity','ship_head_id','JC_ContainerMode','JC_ContainerNum'])
    ->groupBy('ship_head_id','JC_ContainerNum','JC_ContainerMode')
    ->all();

    $shipPackQuery = ShipPack::find()
    ->select(['UM(JL_ActualVolume) AS volume','SUM(JL_ActualWeight) AS weight','JC_ContainerNum')
    ->all();

    $shipHeadQuery = ShipHead::find()
    ->select(['sh.JS_UniqueConsignRef AS shipment','SUM(sp.volume) AS average_volume_cbm','SUM(sp.volume) / SUM(sc.teu) AS average_value','SUM(sp.volume) / SUM(sc.capacity) AS average_value_percent','SUM(sp.weight) AS average_weight','date_format(sh." . $filterField . ",'%b') AS month_name','if(month(sh." . $filterField . ")>=month(now()),month(sh." . $filterField . "),month(sh." . $filterField . ")+12) as months_order)'])
    ->from(ShipHead::tableName() .' AS sh')
    ->leftJoin(['sc' => $shipContainerQuery],"sc.ship_head_id = sh.sh_id AND sc.JC_ContainerMode IN ('FCL','FTL')")
    ->leftJoin(['sp' => $shipPackQuery],'sp.ship_head_id = sh.sh_id AND sp.JC_ContainerNum = sc.JC_ContainerNum')
    ->where(['sh.is_latest' => 1])
    ->andWhere('sh.JS_E_ARV < NOW() - INTERVAL 1 MONTH and sh.JS_E_ARV > Date_add(NOW() - INTERVAL 1 MONTH,interval - 12 month)')
    ->groupBy('sh.sh_id');

    $shipQuery = $shipQuery
    ->addSelect(["SUM(ship.average_value) / COUNT(ship.shipment) AS volume","'teu' as volume_unit","SUM(ship.average_value_percent) / COUNT(ship.shipment) AS average_container_utilization"])

解决方法

代码的主要问题是,您正在子查询中调用all()方法。因此,您可以将它们的结果传递到另一个查询中,而不是将它们作为查询传递。

另一个问题是,在您的php代码中,您正在使用leftJoin,但在原始SQL中,您有JOIN,这意味着INNER JOIN

通过groupBy()指定多列时,您需要使用数组。

您可能希望将更复杂的表达式包装在\yii\db\Expression实例中,以防止Yii在尝试引用表名或列时弄乱您的表达式。

您还可以使用$shipHeadQuery->alias('sh')代替$shipHeadQuery->from(ShipHead::tableName() .' AS sh')向ActiveQuery添加别名。

您可以使用数组为所选列指定别名,以提高可读性。

整个查询可能看起来像这样

//Add following two lines to the other use clauses if they are not already there.
use \yii\db\Expression; 
use \yii\db\Query;

$shipContainerQuery = ShipContainer::find()
    ->select([
        'teu' => new Expression('SUM(RC_TEU)'),'capacity' => new Expression('SUM(RC_Cubiccapacity)'),'ship_head_id','JC_ContainerMode','JC_ContainerNum',])->groupBy(['ship_head_id','JC_ContainerMode']);

$shipPackQuery = ShipPack::find()
    ->select([
        'volume' => new Expression('SUM(JL_ActualVolume)'),'weight' => new Expression('SUM(JL_ActualWeight)'),'JC_ContainerNum']);

$shipHeadQuery = ShipHead::find()
    ->select([
        'shipment' => 'sh.JS_UniqueConsignRef','average_volume_cbm' => new Expression('SUM(sp.volume)'),'average_value' => new Expression('SUM(sp.volume) / SUM(sc.teu)'),'average_value_percent' => new Expression('SUM(sp.volume) / SUM(sc.capacity)'),'average_weight' => new Expression('SUM(sp.weight)'),'month_name' => new Expression("date_format(sh.JS_E_ARV,'%b')"),'months_order' => new Expression('if(month(sh.JS_E_ARV) >= month(now()),month(sh.JS_E_ARV),month(sh.JS_E_ARV) + 12)'),])->alias('sh')
    ->innerJoin(['sc' => $shipContainerQuery],'sc.ship_head_id = sh.sh_id')
    ->innerJoin(['sp' => $shipPackQuery],'sp.ship_head_id = sh.sh_id')
    ->where(['sh.is_latest' => 1])
    ->andWhere('sp.JC_ContainerNum = sc.JC_ContainerNum')
    ->andWhere(['in','sc.JC_ContainerMode',['FCL','FTL']])
    ->andWhere(new Expression('sh.JS_E_ARV < NOW() - INTERVAL 1 MONTH'))
    ->andWhere(new Expression('sh.JS_E_ARV > Date_add(NOW() - INTERVAL 1 MONTH,interval - 12 month)')
    ->groupBy('sh.sh_id');

$shipQuery = new Query()
    ->select([
        'ship.month_name','minimum_container_utilization' => new Expression('MIN(ship.average_value_percent)'),'maximum_container_utilization' => new Expression('MAX(ship.average_value_percent)'),'volume' => new Expression('SUM(ship.average_value) / COUNT(ship.shipment)'),'volume_kgs' => new Expression('SUM(ship.average_weight) / COUNT(ship.shipment)'),'volume_cbm' => new Expression('SUM(ship.average_volume_cbm) / COUNT(ship.shipment)'),'volume_percent' => new Expression('SUM(ship.average_value_percent) / COUNT(ship.shipment)'),])->from(['ship' => $shipHeadQuery])
    ->groupBy(['ship.month_name','ship.months_order'])
    ->orderBy(['ship.months_order' => SORT_ASC]);

然后,您可以通过调用$shipQuery->all()获得结果,也可以在需要的地方使用查询。


因为我没有数据库结构,所以没有测试查询。可能有错别字,或者查询可能需要调试。

,

我建议您仅使用DAO来消除复杂性,将其转换为yii2查询不是一个好主意。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-