我通常喜欢在 tempdb 中设置几个测试表,以便您可以尝试解决方案。我没有在设计中添加任何完整性,因为你有真正的桌子。
-- Just playing
use Tempdb;
Go
--
-- Table 1
--
-- Remove table
if OBJECT_ID('MyPhotos') > 0
drop table MyPhotos
go
-- Simple photo table
create table MyPhotos
(
UserID int,
ImagesFileName varchar(64)
);
-- Some data
insert into MyPhotos values
(1, 'c:\pics\fee.jpg'),
(1, 'c:\pics\fi.jpg'),
(1, 'c:\pics\foo.jpg'),
(1, 'c:\pics\fumb.jpg'),
(2, 'c:\pics\huff.jpg'),
(2, 'c:\pics\n.jpg'),
(2, 'c:\pics\puff.jpg');
-- Show the data
select * from MyPhotos
--
-- Table 2
--
-- Remove table
if OBJECT_ID('UsrTbl') > 0
drop table UsrTbl
go
-- Simple photo table
create table UsrTbl
(
AccountID int,
ScreenName varchar(64)
);
-- Some data
insert into UsrTbl values
(1, 'Jolly Green Giant'),
(2, 'Big Bad Wolf');
-- Show the data
select * from UsrTbl;
解决问题的一种方法是使用公用表表达式。
--
-- Grab a random pic by user id
--
;
WITH ctePhotos
as
(
SELECT
UserID, ImagesFileName,
ROW_NUMBER() OVER (PARTITION BY UserID ORDER BY UserID) as ImgNo
FROM
MyPhotos
),
cteRandomPick
AS
(
SELECT UserID, CEILING(RAND() * MAX(ImgNo)) AS ImgNo
FROM ctePhotos
GROUP BY UserId
)
SELECT
p.UserId,
u.ScreenName,
p.ImgNo,
p.ImagesFileName
FROM UsrTbl as u INNER JOIN ctePhotos as p ON u.AccountID = p.UserID
INNER JOIN cteRandomPick as r ON p.UserID = r.UserID and p.ImgNo = r.ImgNo;
ctePhones 只是通过用户 ID 枚举图片、图片编号。 cteRandomPick 抓取最大值
图片编号并乘以 RAND() 函数得到一张随机图片。
最后但并非最不重要的一点是,body 将两个 CTE 和 User Table 连接起来以获得您的结果。
如果你多次运行代码,你会得到不同的选择。