左外连接只有第一行

时间:2016-11-04 13:36:17

标签: sql sql-server greatest-n-per-group

我的查询类似于

SELECT S.product_id, S.link, C.id AS category_id
FROM Products P
INNER JOIN SEO S ON S.product_id = P.id AND P.product_type = 1
LEFT OUTER JOIN Categories C ON c.product_id = P.id
WHERE P.active = 1

只要每个产品只分配给一个类别,我就能正常工作。但是,如果将产品分配给许多类别,则会返回所有可能的组合。

我是否只能选择第一个产品,如果产品没有任何类别,则仍应使用category_id = NULL返回链接

3 个答案:

答案 0 :(得分:5)

一种简单的方法是使用外部应用,以便具有相关联接,并使其成为前1个查询。因此,您可以访问相关类别记录的所有列。我在这里添加一个类别名称作为例子:

select s.product_id, s.link, c.id as category_id, c.name as category_name
from products p
inner join seo s on s.product_id = p.id 
outer apply
(
  select top 1 * 
  from categories cat
  where cat.product_id = p.id
  order by cat.id
) c
where p.active = 1
and p.product_type = 1;

答案 1 :(得分:3)

您可以使用GROUP BY来完成此操作以及Aggregate功能,最有可能是MINMAX

根据您在结果中偏好的类别ID,您可以选择最小值。

SELECT S.product_id, S.link, MIN(C.id) AS category_id
FROM Products P
INNER JOIN SEO S ON S.product_id = P.id AND P.product_type = 1
LEFT OUTER JOIN Categories C ON c.product_id = P.id
WHERE P.active = 1
GROUP BY S.product_id, S.link

或最大值。

SELECT S.product_id, S.link, MAX(C.id) AS category_id
FROM Products P
INNER JOIN SEO S ON S.product_id = P.id AND P.product_type = 1
LEFT OUTER JOIN Categories C ON c.product_id = P.id
WHERE P.active = 1
GROUP BY S.product_id, S.link

答案 2 :(得分:1)

使用子查询的替代解决方案:

SELECT S.product_id, S.link, 
(
 SELECT C.id FROM Categories C WHERE C.product_id = P.id AND
 ROW_NUMBER() OVER(ORDER BY /* your sort option goes here*/ ) = 1
) AS category_id
FROM Products P
INNER JOIN SEO S ON S.product_id = P.id AND P.product_type = 1
WHERE P.active = 1