在INNER JOIN中选择TOP

时间:2017-02-24 17:05:23

标签: sql sql-server sql-server-2008 tsql sql-server-2008-r2

我在SQL Server中创建了这个简单的数据库:

create database product_test
go

use product_test
go

create table product 
(
    id int identity primary key,
    label varchar(255),
    description text,
    price money, 
);

create table picture 
(
    id int identity primary key, 
    p_path text, 
    product int foreign key references product(id) 
); 

insert into product 
values ('flip phone 100', 'back 2 the future stuff.', 950),
       ('flip phone 200', 's;g material', 1400)

insert into picture 
values ('1.jpg', 1), ('2.jpg', 1), ('3.jpg', 2)

我想要的是为每个产品选择所有产品和仅一个图片。任何帮助是极大的赞赏。

5 个答案:

答案 0 :(得分:3)

为此目的,我是outer apply的粉丝:

select p.*, pi.id, pi.path
from product p outer apply
     (select top 1 pi.*
      from picture pi
      where pi.product = p.id
     ) pi;

您可以添加order by来获取特定图片(例如,ID最低或最高的图片)。或者,order by newid()获得一个随机的。

答案 1 :(得分:1)

我会使用这样的窗口函数:

SELECT *
FROM product 
JOIN (
  SELECT id, product, p_path, 
         row_number() OVER (PARTITION BY product ORDER BY id ASC) as RN
  FROM picture
) pic ON product.id = pic.product AND pic.RN = 1

正如您在此处所见,我选择ID最低的图片(ORDER BY id ASC) - 您可以根据您的要求更改此订单。

答案 2 :(得分:0)

SELECT 
*,
(
    SELECT TOP 1 p2.p_path
    FROM dbo.picture p2
    WHERE p.id = p2.product
) AS picture
FROM dbo.product p

或者加入:

SELECT 
*
FROM dbo.product p
INNER JOIN 
(
    SELECT p2.product, MIN(p2.p_path) AS p_path
    FROM dbo.picture p2
    GROUP BY p2.product
) AS pt
ON p.id = pt.product

但您需要将p_path更改为varchar类型

答案 3 :(得分:0)

您是否尝试过使用相关的子查询?

SELECT *, (SELECT TOP 1 p_path FROM picture WHERE product = p.id ORDER BY id) 
FROM picture p

希望这有帮助,

答案 4 :(得分:-1)

只需分组并取最小或最大
左连接,以防没有图片

select pr.ID, pr.label, pr.text, pr.price
     , min(pic.p_path)
from product pr 
left join picture pic 
on pic.product = pr.ID 
group by pr.ID, pr.label, pr.text, pr.price