如何将来自不同表的多行组合成一行?

时间:2016-07-04 09:22:44

标签: sql sql-server tsql sql-server-2014

我正在尝试取回在我的数据库中注册的所有帐户,并使用图像文件路径查找他们的'个人资料'图像和'封面'图像(脸谱风格)。图像文件路径存储在与account表不同的表中。

我的代码是这样的:

SELECT 
  a1.AccountID, 
 a1.Forename, 
  a1.Surname, 
  img1.Filename AS ProfileImg, 
  img2.Filename AS CoverImg
FROM
  dbo.Account a1
LEFT JOIN
  dbo.AccountImage img1 ON --table with images in
  img1.AccountID = a1.AccountID AND ProfileImg = 1 --boolean column to mark it as profile pic
LEFT JOIN
  dbo.AccountImage img2 ON --table with images in
  img2.AccountID = a1.AccountID and CoverImg = 1 --boolean column to flag as cover pic

帐户表:

AccountID | Forename | Surname |
12345     | Ben      | Hur     |
12346     | Frodo    | Baggins |
12349     | Bill     | Gates   |

AccountImage表:

AccountID | Filename     | ProfileImg | CoverImg
12345     | face.jpg     | True       | NULL
12345     | bg.jpg       | NULL       | True
12346     | graph.png    | NULL       | NULL
12349     | sunset.jpg   | NULL       | True

目前返回:

|AccountID|Forename|Surname|ProfileImg|CoverImg  |
|    12345|     Ben|    Hur|NULL      |bg.jpg    |
|    12345|     Ben|    Hur|face.jpg  |NULL      |

我需要的结果

|AccountID|Forename|Surname|ProfileImg|CoverImg  |
|    12345|     Ben|    Hur|face.jpg  |bg.jpg    |

我只想为每个AccountID返回一行,其中分别包含其帐户详细信息和图像路径(有数百个帐户)。或者我最终得到重复的行 - 一行包含ProfileImg文件路径,另一行包含CoverImg文件路径。

请注意 - 他们可能没有个人资料或封面图片。这意味着两列都可以是NULL

3 个答案:

答案 0 :(得分:2)

试试这个

SELECT 
  a1.AccountID, 
 a1.Forename, 
  a1.Surname, 
  max(img1.Filename) AS ProfileImg, 
  max(img2.Filename) AS CoverImg
FROM
  dbo.Account a1
LEFT JOIN
  dbo.AccountImage img1 ON --table with images in
  img1.AccountID = a1.AccountID AND ProfileImg = 1 --boolean column to mark it as profile pic
LEFT JOIN
  dbo.AccountImage img2 ON --table with images in
  img2.AccountID = a1.AccountID and CoverImg = 2
GROUP BY 
 a1.AccountID, 
 a1.Forename, 
  a1.Surname

答案 1 :(得分:0)

你必须使用内连接而不是左连接

strcmp

答案 2 :(得分:0)

这是一个可以做到的视图。您需要确保在帐户图像表上设置了唯一索引,以防止在特定帐户上设置每种类型的多个图像。

SELECT AccountID, Forename, Surname,
(SELECT TOP (1) Filename
FROM dbo.AccountImage
WHERE (AccountID = dbo.Account.AccountID) AND (ProfileImg <> 0)) AS ProfileImg,
(SELECT TOP (1) Filename
 FROM dbo.AccountImage AS AccountImage_2
 WHERE (AccountID = dbo.Account.AccountID) AND (CoverImg <> 0)) AS CoverImg
FROM dbo.Account
WHERE ((SELECT COUNT(*) AS Expr1
FROM dbo.AccountImage AS AccountImage_1
WHERE (AccountID = dbo.Account.AccountID) AND (ProfileImg <> 0) OR
(AccountID = dbo.Account.AccountID) AND (CoverImg <> 0)) = 2)