Php MySQL连接:如果满足条件,则从子表中选择一行,否则为空
我想把两张桌子合在一起,但遇到了一些麻烦。 这是主表,Php MySQL连接:如果满足条件,则从子表中选择一行,否则为空,php,mysql,join,left-join,Php,Mysql,Join,Left Join,我想把两张桌子合在一起,但遇到了一些麻烦。 这是主表,packs 这是第二张表,media 媒体用于存储包的图像。每个包可以有0个或多个图像。当包中有图像时,其中一个将把is_default字段设置为1,以指示要显示的主图像 我想得到所有的包和一个图像为每个。如果没有图像,则只需一个简单的NULL,否则得到的图像为默认值 这是我的问题 SELECT pack.*, ( SELECT media.src FROM packs pack LEFT JOIN packs_medi
packs
这是第二张表,media
媒体
用于存储包
的图像。每个包可以有0个或多个图像。当包中有图像时,其中一个将把is_default
字段设置为1
,以指示要显示的主图像
我想得到所有的包和一个图像为每个。如果没有图像,则只需一个简单的NULL
,否则得到的图像为默认值
这是我的问题
SELECT
pack.*,
( SELECT media.src FROM packs pack LEFT JOIN packs_media media ON pack.id = media.pack_id WHERE media.is_default = 1 GROUP BY media.id LIMIT 1 ) AS image
FROM packs pack
LEFT JOIN packs_media ON media.pack_id = pack.id
GROUP BY pack.id
ORDER BY pack.id DESC
我一共有三个包,其中只有一个有一些图片。
查询返回3个结果。问题是这三个结果都具有相同的图像
,而只有一个结果应该具有图像
字段null/空
有没有办法只用一个查询就可以做到这一点?我希望避免在循环中查询媒体
表
谢谢您需要的是相关子查询,而不是联接:
SELECT p.*,
(SELECT m.src
FROM packs_media m
WHERE p.id = media.p
ORDER BY m.is_default DESC, m.id
LIMIT 1
) AS image
FROM packs p
ORDER BY p.id DESC;
事实上,从问题的描述来看,外部查询中也不需要JOIN
。因此,也不需要分组依据
注意对ORDER BY
子句的更改。这将确保首先选择默认值
并且,您的查询为所有行获取相同的值,因为子查询独立于外部查询。所以,总是选择相同的值。我最近遇到了一个类似的问题,老实说,它有一个非常好的解决方案。乍一看,一个明显的尝试是添加,其中条件为默认值=1
。但是,如果我们这样做,在没有图像的情况下,条件将不会满足,这意味着它应该返回NULL
,它只会跳过该行
但是,如果您像我一样将此条件添加到左连接
部分,它就像一个符咒。这是因为,根据左连接的定义,如果左连接
条件满足,则返回图像;如果不满足,则返回NULL
因此,结果应该是:
SELECT pack.*, media.src
FROM packs pack
LEFT JOIN media
ON media.pack_id = pack.id
AND media.is_default = 1
我认为你不应该加入群体,它只是把事情搞砸了
如果您想在没有的情况下解决您的问题,则默认为。。。好吧,这是一个更难破解的问题,但我想我有一个解决方案,它不会停留在长长的条件行和子查询中。遗憾的是,我觉得这个问题没有子查询是无法解决的。我的想法不是选择其媒体默认值等于1
的项目,而是选择媒体默认值最高的项目。详情如下:
SELECT pack.*, media.src
FROM packs pack
LEFT JOIN media
ON media.pack_id = pack.id
AND media.id =
(SELECT m.id FROM media m
WHERE m.pack_id = media.pack_id
ORDER BY m.is_default DESC
LIMIT 1
)
说明:这就是它的工作原理:我们按is_default
降序排列所有的数据,然后返回到外部查询,只使用当前的包id
(我希望它是这样工作的)。如果有1,它显然将是第一项,否则它将是随机项,最有可能的是ID的第一个顺序。你只需要取那个元素并使用它。我不能保证它是否有效。尝试在
中使用,而不是=
作为可能的错误修复
但是,我不建议这个解决方案。我宁愿更改以前的逻辑以避免此问题(例如,当用户将介质添加到空包中时,is_default=1
在该图片上)。m.is_default=1按m.is_default
?谢谢。它确实有效。只是一个简单的问题。如果有图像但没有一个具有is_default=1,是否仍然可以获得一个?现在,如果一个包有图像但没有默认值,它将返回null。@C.Ovidiu-删除子查询中的和m.is_default=1
条件,非常感谢您。它工作得很好,看起来很干净。您是否介意告诉我,如果is_默认字段不是1,但包中仍有图像,是否可以选择第一个图像?如果是1,则获取该图像。否则,获取第一个或仅另一个图像,以便该包至少有一个图像。如果包中没有,则为空。我将答案更改为回复您的评论。我希望这能有所帮助,但我确实在努力推动改变代码的另一部分,使这一部分更容易。相信我,你最好想要两个你能理解的小问题,而不是一周后你甚至都记不起来的一个长问题。