我想加入两个表,但只能获得table1上每条记录的table2记录
例如:
SELECT c.id, c.title, p.id AS product_id, p.title
FROM categories AS c
JOIN products AS p ON c.id = p.category_id
这会让我得到products
中的所有记录,这不是我想要的。我想要每个类别1个[第一个]产品(我在产品领域有一个sort
列。)
我该怎么做?
答案 0 :(得分:52)
我更喜欢在类似问题中描述的另一种方法:https://stackoverflow.com/a/11885521/2215679
这种方法更好,尤其是在需要在SELECT中显示多个字段的情况下。为了避免每列的Error Code: 1241. Operand should contain 1 column(s)
或双子选择。
对于您的情况,查询应如下所示:
SELECT
c.id,
c.title,
p.id AS product_id,
p.title AS product_title
FROM categories AS c
JOIN products AS p ON
p.id = ( --- the PRIMARY KEY
SELECT p1.id FROM products AS p1
WHERE c.id=p1.category_id
ORDER BY p1.id LIMIT 1
)
答案 1 :(得分:21)
@ goggin13接受的回答看起来不对。到目前为止提供的其他解决方案都可以使用,但是遇到了n + 1问题,因此会受到性能影响。
n + 1问题:如果有100个类别,那么我们必须做1个选择来获取类别,然后对于返回的100个类别中的每个类别,我们需要选择以获取该类别中的产品。因此将执行101个SELECT查询。
我的替代解决方案解决了n + 1问题,因此只需要执行2次选择就可以显着提高性能。
SELECT
*
FROM
(SELECT c.id, c.title, p.id AS product_id, p.title
FROM categories AS c
JOIN products AS p ON c.id = p.category_id
ORDER BY c.id ASC) AS a
GROUP BY id;
答案 2 :(得分:8)
SELECT c.id, c.title, p.id AS product_id, p.title
FROM categories AS c
JOIN products AS p ON c.id = p.category_id
GROUP BY c.id
这将返回产品中的第一个数据(等于限制1)
答案 3 :(得分:2)
这个怎么样?
SELECT c.id, c.title, (SELECT id from products AS p
WHERE c.id = p.category_id
ORDER BY ...
LIMIT 1)
FROM categories AS c;
答案 4 :(得分:1)
With子句可以解决这个问题。像这样:
WITH SELECTION AS (SELECT id FROM products LIMIT 1)
SELECT a.id, c.id, c.title FROM selection a JOIN categories c ON (c.id = a.id);
答案 5 :(得分:0)
假设您希望MIN()
列中的sort
imial值的产品看起来像这样。
SELECT
c.id, c.title, p.id AS product_id, p.title
FROM
categories AS c
INNER JOIN (
SELECT
p.id, p.category_id, p.title
FROM
products AS p
CROSS JOIN (
SELECT p.category_id, MIN(sort) AS sort
FROM products
GROUP BY category_id
) AS sq USING (category_id)
) AS p ON c.id = p.category_id
答案 6 :(得分:0)
使用postgres时,可以使用DISTINCT ON
语法来限制从任何一个表返回的列数。
以下是代码示例:
SELECT c.id, c.title, p.id AS product_id, p.title
FROM categories AS c
JOIN (
SELECT DISTINCT ON(p1.id) id, p1.title, p1.category_id
FROM products p1
) p ON (c.id = p.category_id)
诀窍是不要直接在表上多次出现id的表上联接,而是先创建一个表,每个表只出现一次id
答案 7 :(得分:0)
另一个带有3个嵌套表的示例: 1 /用户 2 / UserRoleCompanie 3 /同伴
SELECT
u.id as userId,
u.firstName,
u.lastName,
u.email,
urc.id ,
urc.companieRole,
c.id as companieId,
c.name as companieName
FROM User as u
JOIN UserRoleCompanie as urc ON u.id = urc.userId
AND urc.id = (
SELECT urc2.id
FROM UserRoleCompanie urc2
JOIN Companie ON urc2.companieId = Companie.id
AND urc2.userId = u.id
AND Companie.isPersonal = false
order by Companie.createdAt DESC
limit 1
)
LEFT JOIN Companie as c ON urc.companieId = c.id
+---------------------------+-----------+--------------------+---------------------------+---------------------------+--------------+---------------------------+-------------------+
| userId | firstName | lastName | email | id | companieRole | companieId | companieName |
+---------------------------+-----------+--------------------+---------------------------+---------------------------+--------------+---------------------------+-------------------+
| cjjt9s9iw037f0748raxmnnde | henry | pierrot | henry@gmail.com | cjtuflye81dwt0748e4hnkiv0 | OWNER | cjtuflye71dws0748r7vtuqmg | leclerc |
答案 8 :(得分:-1)
在我看来,这是最好的答案(使其通用):
SELECT
TB1.Id
FROM Table1 AS TB1
INNER JOIN Table2 AS TB2 ON (TB1.Id = TB2.Id_TB1)
AND TB2.Id = (
SELECT Id
FROM Table2
WHERE TB1.Id = Id_TB1
ORDER BY Table2.Id DESC
LIMIT 1
)
答案 9 :(得分:-3)
用你的表替换表:
SELECT * FROM works w
LEFT JOIN
(SELECT photoPath, photoUrl, videoUrl FROM workmedias LIMIT 1) AS wm ON wm.idWork = w.idWork
答案 10 :(得分:-20)
我会尝试这样的事情:
SELECT C.*,
(SELECT P.id, P.title
FROM products as P
WHERE P.category_id = C.id
LIMIT 1)
FROM categories C