当 运行 `SELECT INNER JOIN WHERE t1.column=t2.column` 并且有多个匹配项时,您如何控制选择哪个匹配项?
How do you control which match is chosen when running a `SELECT INNER JOIN WHERE t1.column=t2.column` and there are multiple matches?
我有两个 MySQL 表:
产品
title id hidden categories
Thing 10 N 12,14,
Stuff 23 N 12,
Object 41 Y 13,14
图片
filename id productid
aca8t.jpg 1 10
ev7ha.jpg 2 10
mscpk.jpg 3 10
asges.jpg 4 23
fcuhg.jpg 5 23
scvfe.jpg 6 41
vf6kl.jpg 7 41
fgszy.jpg 8 41
我使用如下 SELECT 语句构建产品标题和图片列表:
SELECT t1.title,
t1.id,
t1.hidden,
t1.categories,
t2.image
FROM products AS t1
INNER JOIN pimage AS t2
WHERE t1.categories LIKE '%$categoryId%'
AND t1.id=t2.productid
AND NOT t1.hidden='Y'
GROUP BY id
ORDER BY id ASC
在 运行 这个查询之后,我得到了给定类别中 non-hidden 产品的列表,以及它们的 ID 和一张图片。然而,图像的选择似乎是随机的。有时它是按字母顺序排列的,有时它是最低 ID,有时两者都不是。但是,当给定 productid 的文件名保持不变时,它总是相同的。
这是在一个小型网站上使用的,产品经理在该网站上上传产品及其配件的照片。第一张照片应用作缩略图并在类别页面上可见。但是,有时会选择随机配饰的照片作为缩略图,产品经理必须 re-upload 图片直到选择正确的图片。这个过程很繁琐。
如何修改 SQL 语句以便选择第一张照片(具有最低 images.id
的文件名)?
尝试使用相关子查询而不是 join
/group by
:
SELECT p.*,
(SELECT i.image
FROM pimage i
WHERE p.id = i.productid
ORDER BY i.image ASC
LIMIT 1
) as image
FROM products p
WHERE p.categories LIKE '%$categoryId%' AND
p.hidden <> 'Y'
ORDER BY p.id ASC
如果此语句在另一个关系数据库(MySQL/MariaDB 除外)上执行,它会抛出一条错误消息,并显示 "non-aggregates in SELECT list not included in GROUP BY".
行的消息
但是 GROUP BY 的 MySQL 特定扩展允许此查询在 MySQL 中执行,但正如您所注意到的,return 中的非聚合值SELECT 列表是 不确定的,MySQL 将 return 来自 一些 行的值。
正常模式是使用 MAX()
或 MIN()
聚合函数到 "control",其值为 returned。
在您的情况下,这将适用于 return 最小 id
值,但在同一行上获取其他值更成问题。如果只需要return几列,可以在SELECT列表中使用相关子查询。
另一种方法是使用内联视图和连接操作。
SELECT t1.title
, t1.id
, t1.hidden
, t1.categories
, t2.image
FROM products t1
JOIN ( SELECT n.productid
, MIN(n.id) AS min_id
FROM pimage n
GROUP BY n.productid
) m
ON m.productid = t1.id
JOIN pimage t2
ON t2.id = m.min_id
WHERE t1.categories LIKE '%$categoryId%'
AND t1.hidden='Y'
GROUP BY t1.id
ORDER BY t1.id ASC
当您需要从具有 "minimum" ID 的行中 return 额外的列时,此方法很有用。例如,您还需要在 SELECT 列表中包括:
, t2.fee
, t2.fi
, t2.fo
, t2.fum
我有两个 MySQL 表:
产品
title id hidden categories
Thing 10 N 12,14,
Stuff 23 N 12,
Object 41 Y 13,14
图片
filename id productid
aca8t.jpg 1 10
ev7ha.jpg 2 10
mscpk.jpg 3 10
asges.jpg 4 23
fcuhg.jpg 5 23
scvfe.jpg 6 41
vf6kl.jpg 7 41
fgszy.jpg 8 41
我使用如下 SELECT 语句构建产品标题和图片列表:
SELECT t1.title,
t1.id,
t1.hidden,
t1.categories,
t2.image
FROM products AS t1
INNER JOIN pimage AS t2
WHERE t1.categories LIKE '%$categoryId%'
AND t1.id=t2.productid
AND NOT t1.hidden='Y'
GROUP BY id
ORDER BY id ASC
在 运行 这个查询之后,我得到了给定类别中 non-hidden 产品的列表,以及它们的 ID 和一张图片。然而,图像的选择似乎是随机的。有时它是按字母顺序排列的,有时它是最低 ID,有时两者都不是。但是,当给定 productid 的文件名保持不变时,它总是相同的。
这是在一个小型网站上使用的,产品经理在该网站上上传产品及其配件的照片。第一张照片应用作缩略图并在类别页面上可见。但是,有时会选择随机配饰的照片作为缩略图,产品经理必须 re-upload 图片直到选择正确的图片。这个过程很繁琐。
如何修改 SQL 语句以便选择第一张照片(具有最低 images.id
的文件名)?
尝试使用相关子查询而不是 join
/group by
:
SELECT p.*,
(SELECT i.image
FROM pimage i
WHERE p.id = i.productid
ORDER BY i.image ASC
LIMIT 1
) as image
FROM products p
WHERE p.categories LIKE '%$categoryId%' AND
p.hidden <> 'Y'
ORDER BY p.id ASC
如果此语句在另一个关系数据库(MySQL/MariaDB 除外)上执行,它会抛出一条错误消息,并显示 "non-aggregates in SELECT list not included in GROUP BY".
行的消息但是 GROUP BY 的 MySQL 特定扩展允许此查询在 MySQL 中执行,但正如您所注意到的,return 中的非聚合值SELECT 列表是 不确定的,MySQL 将 return 来自 一些 行的值。
正常模式是使用 MAX()
或 MIN()
聚合函数到 "control",其值为 returned。
在您的情况下,这将适用于 return 最小 id
值,但在同一行上获取其他值更成问题。如果只需要return几列,可以在SELECT列表中使用相关子查询。
另一种方法是使用内联视图和连接操作。
SELECT t1.title
, t1.id
, t1.hidden
, t1.categories
, t2.image
FROM products t1
JOIN ( SELECT n.productid
, MIN(n.id) AS min_id
FROM pimage n
GROUP BY n.productid
) m
ON m.productid = t1.id
JOIN pimage t2
ON t2.id = m.min_id
WHERE t1.categories LIKE '%$categoryId%'
AND t1.hidden='Y'
GROUP BY t1.id
ORDER BY t1.id ASC
当您需要从具有 "minimum" ID 的行中 return 额外的列时,此方法很有用。例如,您还需要在 SELECT 列表中包括:
, t2.fee
, t2.fi
, t2.fo
, t2.fum