views:

82

answers:

4

Database has tables Photos and PhotoAlbums. I need a query that will select all albums and only one photo from each album. I need SQL and LINQ version of this query. Thanks in advance.

+1  A: 

In Linq I'm not that experienced in it so I'll only give the SQL Server Query

SELECT a.*,b.MyPhoto FROM PhotoAlbums a,(SELECT Top 1 myPhoto from Photos Where AlbumID = a.ID) b

Or This

SELECT a.AlbumID, a.Title, a.Date, (SELECT TOP (1) c.PhotoID FROM Photos c WHERE(c.AlbumID = a.AlbumID)) AS PhotoID FROM PhotoAlbums as a
Kronass
Please, see my new question
ile
+1  A: 

if the tables are like:

PhotoAlbums
AlbumID    PK
...

Photos
PhotoID    PK
AlbumID    FK
Photo
...

Here is the SQL query:

SELECT
    a.*,p.Photo 
    FROM PhotoAlbums a
        LEFT OUTER JOIN (SELECT
                             AlbumID,MIN(PhotoID) AS MinPhotoID
                             FROM Photos
                             GROUP BY AlbumID
                        ) dt ON a.AlbumID=dt.AlbumID
        LEFT OUTER JOIN Photos p ON dt.MinPhotoID=p.PhotoID

working example:

DECLARE @PhotoAlbums table (AlbumID  int)
INSERT @PhotoAlbums VALUES (1)
INSERT @PhotoAlbums VALUES (2)
INSERT @PhotoAlbums VALUES (3)

DECLARE @Photos table (PhotoID int,AlbumID int, Photo varchar(10))
INSERT @Photos VALUES (1,1,'A')
INSERT @Photos VALUES (2,1,'B')
INSERT @Photos VALUES (3,1,'C')
INSERT @Photos VALUES (4,2,'AA')
INSERT @Photos VALUES (5,3,'AAA')
INSERT @Photos VALUES (6,3,'BBB')

SELECT
    a.*,p.Photo 
    FROM @PhotoAlbums a
        LEFT OUTER JOIN (SELECT
                             AlbumID,MIN(PhotoID) AS MinPhotoID
                             FROM @Photos
                             GROUP BY AlbumID
                        ) dt ON a.AlbumID=dt.AlbumID
        LEFT OUTER JOIN @Photos p ON dt.MinPhotoID=p.PhotoID

OUTPUT:

AlbumID     Photo
----------- ----------
1           A
2           AA
3           AAA

(3 row(s) affected)
KM
hmmm... When I try to execute your and Kronass's query, VS2008 formats the query and then returns error. Is SQL the same for MySQL and MSSQL?
ile
And yes, the tables are like you assumed
ile
and the error message would be?
KM
If I click Execute, error is following: "Error in GROUP BY clause.Unable to parse query text." If I click Verify Syntax, error is: "Incorrect syntax near 'a' "
ile
See latest edit, I missed the `ON` here: `) dt ON a.AlbumID=`, I also added a working example.
KM
It's working now, thanks a lot. It's a bit complex to understand for me... What does 'dt' stand for? I suppose it stands for Photos table but I'm used to make alias of expression with 'AS'.
ile
You wouldn't know LINQ version of this query?
ile
the `LEFT OUTER JOIN (SELECT ...) dt` is a derived table, also known as an inline view. It is a query that gets joined into the main query just like it was its own table. I use it to get 1 photo per album. I then need to join back to the Photos table using this Min =PhotoId to get the other columns form the Photos table. I've never used LINQ, so I can't help there.
KM
Thank you for detail explanation!
ile
A: 

@Kronass
I'm trying to make your Query work but I'm not succeeding. I tried this:

SELECT     a.AlbumID, a.Title, a.Date, b.PhotoID
FROM         PhotoAlbums AS a CROSS JOIN
                          (SELECT     TOP (1) PhotoID, AlbumID
                            FROM          Photos
                            WHERE      (AlbumID = a.AlbumID)) AS b

But I always get following error:
The multi-part identifier "a.AlbumID" could not be bound.
Do you know what is wrong in this code?

ile
Try ThisSELECT a.AlbumID, a.Title, a.Date, (SELECT TOP (1) c.PhotoID FROM Photos c WHERE(c.AlbumID = a.AlbumID)) AS PhotoID FROM PhotoAlbums as a
Kronass
This one works. Thank you!
ile
+1  A: 

The Linq query could be something like this:

from album in context.PhotoAlbums
from photo in album.Photos.Take(1).DefaultIfEmpty()
select new
   {
        Album = album,
        Photo = photo
   }
Mike
This works! Thanks
ile