1) No matter how many times the photoblob appears in your result set it will be read(from Disk to memory in the server) only once, There are optimizations built in to make sure this is happening.
2) However it can be transported(from server to client) multiple times, there are no optimization built in for that.
3) The best solution would be to wrap this as a stored procedure that returns 2 record sets, and you do the join in the clinet code, this approach is different from running 2 queries which needs two round trip.
4) if you dont want to do that you can get all the article ids of the user in a CSV format, and then you can easily split the csv into separate strings in the client code.
Here is the sample output
UserId UserName UserPhoto CSV_ArticleId CSV_ArticleText
------- --------- ---------- ------------------------ ----------------------------
UserId1 UserName1 UserPhoto1 ",ArticleId1,ArticleId2" ",ArticleText1,ArticleText2"
UserId2 UserName2 UserPhoto2 ",ArticleId3" ",ArticleText3"
here is how you can do it. Run the code verbatim on a test database and you can see the result
CREATE TABLE Users(UserId int , UserName nvarchar(256), UserPhoto nvarchar(256))
CREATE TABLE Articles (ArticleId int , UserId int , ArticleText nvarchar(256))
INSERT INTO Users(UserId,UserName,UserPhoto)
VALUES (2,'2a','2pa')
INSERT INTO Users(UserId,UserName,UserPhoto)
VALUES (1,'a','pa')
INSERt INTO Articles (ArticleId, UserId, ArticleText)
VALUES (2,2,'text2')
INSERt INTO Articles (ArticleId, UserId, ArticleText)
VALUES (1,2,'text1')
;WITH tArticles AS (SELECT ArticleId, UserId, ArticleText FROM Articles)
SELECT
UserId,
UserName,
UserPhoto,
(SELECT TOP 1 LTRIM(
(SELECT ',' + CONVERT(nvarchar(256),A.ArticleId) FROM Articles A WHERE U.UserId = A.UserId ORDER BY A.ArticleId FOR XML PATH(''))
)) as CSV_ArticleId,
(SELECT TOP 1 LTRIM(
(SELECT ',' + CONVERT(nvarchar(256),A.ArticleText) FROM Articles A WHERE U.UserId = A.UserId ORDER BY A.ArticleId FOR XML PATH(''))
)) as CSV_ArticleText
FROM Users U