没有不值得去解决的问题,也没有不值得去学习的技术!

How to Avoid Redundant Values in an IN Clause When Joining the Image Model Only if Type=5 in Yii2

However, only '1827082629732850' and '1827082629732857' correspond to type=5; the other ids have type != 5

1. The current implementation is as follows

PHP

$informations = ConventionCustomerServiceInformation::find()->select('id, group_id, type, label, value')->where([
	'convention_id' => $conventionId,
])->with(['image'])->orderBy('order_number ASC')->asArray()->all();

public function getImage(): ActiveQuery
{
	return $this->hasOne(Image::class, ['id' => 'value']);
}

2. The generated SQL is as follows

SQL

SELECT * FROM `images` WHERE `id` IN ('7777', '55550', '333', '66', '地址', '1827082629732850', '88', '1827082629732857')

3. However, only ‘1827082629732850’ and ‘1827082629732857’ correspond to type=5; the other ids have type != 5. See Figure 1

However, only '1827082629732850' and '1827082629732857' correspond to type=5; the other ids have type != 5
Figure 1

4. Collect all values where type=5 (i.e., image ids), batch query the corresponding images, and attach the image data. The revised implementation is as follows

PHP

	$informations = ConventionCustomerServiceInformation::find()->select('id, group_id, type, label, value')->where([
		'convention_id' => $conventionId,
	])->orderBy('order_number ASC')->asArray()->all();

	// 批量查询对应图片
	$images = [];
	$imageIds = $this->getImageValuesFrom($informations);
	if (!empty($imageIds)) {
		$images = Image::find()
			->where(['id' => $imageIds])
			->indexBy('id')
			->asArray()
			->all();
	}

	foreach($informations as $info){
		if ($info['type'] == ConventionCustomerServiceInformation::TYPE_IMAGE) {
			$info['image'] = $images[$info['value']] ?? null;
		} else {
			$info['image'] = null;
		}
		$mappings[$info['group_id']]['informations'][] = $info;
	}

    /**
     * 获取所有 type = 5 的 value,即所有的图片
     * @param array $models
     * @return array
     */
    private function getImageValuesFrom(array $models): array
    {
        return ArrayHelper::getColumn(
            array_filter($models, function ($model) {
                return $model['type'] == ConventionCustomerServiceInformation::TYPE_IMAGE;
            }),
            'value'
        );
    }

5. The generated SQL is as follows, which meets expectations

SQL

SELECT * FROM `images` WHERE `id` IN ('1827082629732850', '1827082629732857')

关于作者 · 持续学习与技术实践

我是一名拥有 15 年以上开发经验的技术从业者,自 2013 年起持续运营个人技术博客,记录工作与个人项目中遇到的真实问题,以及解决问题过程中的探索、实践和思考。

除了技术写作,我也在持续开发和维护自己的独立项目,探索新技术和新工具在实际场景中的应用。我始终相信,没有不值得去解决的问题,也没有不值得去学习的技术。

如果这篇文章对你有所帮助,欢迎浏览博客中的其他文章,也欢迎交流技术经验与想法。

关于我  ·  GitHub  ·  邮件联系