Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Yii2-多重条件下的左连接_Php_Mysql_Yii2 - Fatal编程技术网

Php Yii2-多重条件下的左连接

Php Yii2-多重条件下的左连接,php,mysql,yii2,Php,Mysql,Yii2,我有三张表,它们的关系如下: ------- 1 0..* ------------ |Product|-------------|Availability| ------- ------------ 1 | | 1 | -------- |MetaData| -------- 我的原始sql如下所示 SELECT p.ID FROM product p LEFT JOIN availability a

我有三张表,它们的关系如下:

  ------- 1        0..* ------------
 |Product|-------------|Availability|
  -------               ------------
    1 |
      |
    1 |
  --------
 |MetaData|
  --------
我的原始sql如下所示

SELECT p.ID FROM product p 
LEFT JOIN availability a ON a.productID=p.ID 
          AND a.start>=DATE_ADD(DATE(now()), INTERVAL 7 DAY)
LEFT JOIN meta_data m ON m.ID=p.meta_dataID
WHERE a.ID IS NULL
AND m.published_state=1;
也就是说,查找具有
元数据的
产品。
发布状态等于
1
且不具有
可用性的
产品。
可用性。从
开始
超过7天(

我正在尝试使用
ActiveRecord
方法来完成同样的任务,使用类似以下的方法

$products = Product::find()
            ->joinWith('metaData')
            ->joinWith('availability')
            ->onCondition(['>=', 'availability.start', strtotime('+7 days')])
            ->where(['is', 'availability.ID', NULL])
            ->andWhere(['=', 'meta_data.published_state', 1])
            ->all();
然而,这并没有产生任何结果。使用
Connection::createCommand()
运行原始sql将返回我期望的行,因此数据没有问题

我怀疑问题是由
join
条件和
where
条件相互“出血”引起的;联接和where都应用于联接或where,而不是单独应用

如何输出正在运行的实际sql查询?这是在从控制台控制器调用的操作中


如何更改代码以返回所需的
产品

只需按以下条件使用即可

$query = Product::find()
 -> leftJoin('availability', 'availability.productID=product.ID  AND a.start>=DATE_ADD(DATE(now()), INTERVAL 7 DAY)')
 ->leftJoin('meta_data', 'meta_data.ID=product.meta_dataID')
 ->where(['is', 'availability.ID', NULL])
 ->andWhere(['=', 'meta_data.published_state', 1])
 ->all();

我相信这是一个更好的解决方案。不要使用像
leftJoin
这样的原始查询,而应该使用
andOnCondition
的关系来补充
join(这会在join语句中添加所需的where条件)

此外,在关系中编写
where
子句时,它看起来更干净。它的工作原理与在外部写入相同(如果我没有错的话),但在重构查询时,您可以轻松删除整个关系,而不会忘记外部的关系条件。

使用以下方法:

$sql = 'SELECT p.ID FROM product p 
LEFT JOIN availability a ON a.productID=p.ID 
          AND a.start>=DATE_ADD(DATE(now()), INTERVAL 7 DAY)
LEFT JOIN meta_data m ON m.ID=p.meta_dataID
WHERE a.ID IS NULL
AND m.published_state=1';

$products = Product::findBySql($sql);
Yii Active Record有一个方法,允许您使用原始SQL查询从数据库中运行和获取数据。当您对Yii的查询方法感到困惑时,或者当您的查询使用Yii运行时变得更加复杂时,我想这会有很大帮助


因此,基本上,在上面的代码块中,您只需将原始SQL查询放入一个名为
$SQL
的变量,并将其用作
findBySql()
方法的参数值。

它只提供产品的数据,而不提供可用性和元数据。如何在结果中同时显示这两个关系。您使用的是原始的LeftJoin,而不是Yii2关系。最好用额外的条件来补充目前的关系。非常非常有帮助。只需注意
ActiveQuery
名称空间是
\yii\db\ActiveQuery
,请编辑您的答案,包括此代码如何工作以及如何解决问题的解释。已编辑。希望能有帮助。
$sql = 'SELECT p.ID FROM product p 
LEFT JOIN availability a ON a.productID=p.ID 
          AND a.start>=DATE_ADD(DATE(now()), INTERVAL 7 DAY)
LEFT JOIN meta_data m ON m.ID=p.meta_dataID
WHERE a.ID IS NULL
AND m.published_state=1';

$products = Product::findBySql($sql);