目前我正在执行以下操作:
SELECT SiteFeatures.SiteId, Blogs.FeatureInstance_Id as BlogId,
PageCollections.FeatureInstance_Id as PagesId,
Portfolios.FeatureInstance_Id as PortfolioId
FROM SiteFeatures
LEFT OUTER JOIN Blogs
ON SiteFeatures.FeatureInstanceId = Blogs.FeatureInstance_id
LEFT OUTER JOIN Portfolios
ON SiteFeatures.FeatureInstanceId = Portfolios.FeatureInstance_id
LEFT OUTER JOIN PageCollections
ON SiteFeatures.FeatureInstanceId = PageCollections.FeatureInstance_id
这将返回如下结果集:
SiteId BlogId PagesId PortfolioId
1 1 NULL NULL
1 NULL 1 NULL
1 NULL NULL 1
2 2 NULL NULL
2 NULL 2 NULL
2 NULL NULL 2
这意味着我必须在我的应用程序代码中聚合这些内容。如何更改我的查询(以性能为准)返回:
SiteId BlogId PagesId PortfolioId
1 1 1 1
1 2 2 2
根据要求 - 我的架构:
答案 0 :(得分:3)
SELECT SiteFeatures.SiteId
, MAX(Blogs.FeatureInstance_Id) as BlogId
, MAX(PageCollections.FeatureInstance_Id) as PagesId
, MAX(Portfolios.FeatureInstance_Id) as PortfolioId
FROM SiteFeatures
LEFT OUTER JOIN Blogs
ON SiteFeatures.FeatureInstanceId = Blogs.FeatureInstance_id
LEFT OUTER JOIN Portfolios
ON SiteFeatures.FeatureInstanceId = Portfolios.FeatureInstance_id
LEFT OUTER JOIN PageCollections
ON SiteFeatures.FeatureInstanceId = PageCollections.FeatureInstance_id
GROUP BY SiteFeatures.SiteId
ORDER BY SiteFeatures.SiteId ASC
答案 1 :(得分:3)
SELECT
S.SiteId,
B.FeatureInstance_Id BlogId,
P.FeatureInstance_Id PortfolioId,
C.FeatureInstance_Id PagesId
FROM
Sites S
LEFT JOIN (
SiteFeatures F1
INNER JOIN Blogs B ON F1.FeatureInstanceId = B.FeatureInstance_id
) ON S.SiteID = F1.SiteID
LEFT JOIN (
SiteFeatures F2
INNER JOIN Portfolios P ON F2.FeatureInstanceId = P.FeatureInstance_id
) ON S.SiteID = F2.SiteID
LEFT JOIN (
SiteFeatures F3
LEFT JOIN PageCollections C ON F3.FeatureInstanceId = C.FeatureInstance_id
) ON S.SiteID = F3.SiteID
假设您的所有子表每个FeatureInstance_Id
只能有一行,这应该可以正常工作。
如果你设计了数据库,那么你就可以在表格中找到不一致的列名,从而获得了很好的说唱力。 :)
如果此查询有效,那么您可以考虑将其封装在一系列视图中,这些视图会将查询返回到一个非常紧凑的东西:
CREATE VIEW BlogsFeature
AS
SELECT
F.*
FROM
SiteFeatures F
WHERE EXISTS ( -- or you could do an INNER JOIN, though in theory this is correct
SELECT 1
FROM Blogs B
WHERE F.FeatureInstanceId = B.FeatureInstance_id
)
对所有三个表执行此操作将产生以下查询:
SELECT
S.SiteId,
B.FeatureInstance_Id BlogId,
P.FeatureInstance_Id PortfolioId,
C.FeatureInstance_Id PagesId
FROM
Sites S
LEFT JOIN BlogsFeature B ON S.SiteID = B.SiteID
LEFT JOIN PortfoliosFeature P ON S.SiteID = P.SiteID
LEFT JOIN PageCollections C O ON S.SiteID = C.SiteID
实际上,这让我想到了另一种表达你需要的查询的方法,虽然它仍然不是很漂亮:
SELECT
S.SiteId,
F1.FeatureInstance_Id BlogId,
F2.FeatureInstance_Id PortfolioId,
F3.FeatureInstance_Id PagesId
FROM
Sites S
LEFT JOIN SiteFeatures F1
ON S.SiteID = F1.SiteID
AND EXISTS (
SELECT 1 FROM Blogs B
WHERE F1.FeatureInstanceId = B.FeatureInstance_id
)
LEFT JOIN SiteFeatures F2
ON S.SiteID = F2.SiteID
AND EXISTS (
SELECT 1 FROM Portfolios P
WHERE F2.FeatureInstanceId = P.FeatureInstance_id
)
LEFT JOIN SiteFeatures F3
ON S.SiteID = F3.SiteID
AND EXISTS (
SELECT 1 FROM PageCollections C
WHERE F3.FeatureInstanceId = C.FeatureInstance_id
)
如果您将uniqueidentifier临时转换为字符串,则可以使用Max()的想法。
SELECT
S.SiteId,
B.FeatureInstance_Id BlogId,
P.FeatureInstance_Id PortfolioId,
C.FeatureInstance_Id PagesId
FROM
SiteFeatures F
INNER JOIN Blogs B ON
答案 2 :(得分:1)
您是否尝试使用INNER JOIN
而不是LEFT JOIN
s?
SELECT SiteFeatures.SiteId
, Blogs.FeatureInstance_Id as BlogId
, PageCollections.FeatureInstance_Id as PagesId
, Portfolios.FeatureInstance_Id as PortfolioId
FROM SiteFeatures
INNER JOIN Blogs
ON SiteFeatures.FeatureInstanceId = Blogs.FeatureInstance_id
INNER JOIN Portfolios
ON SiteFeatures.FeatureInstanceId = Portfolios.FeatureInstance_id
INNER JOIN PageCollections
ON SiteFeatures.FeatureInstanceId = PageCollections.FeatureInstance_id
第二个想法,这可能是你想要的:
SELECT sf.SiteId
, ( SELECT b.FeatureInstance_Id
FROM Blogs AS b
WHERE sf.FeatureInstanceId = b.FeatureInstance_id
) AS BlogId
, ( SELECT pc.FeatureInstance_Id
FROM PageCollections AS pc
WHERE sf.FeatureInstanceId = pc.FeatureInstance_id
) AS PagesId
, ( SELECT p.FeatureInstance_Id
FROM Portfolios AS p
WHERE sf.FeatureInstanceId = p.FeatureInstance_id
) AS PortfolioId
FROM SiteFeatures AS sf
在第三个想法(并且在看到Eric的答案被接受之后)之后,我将再试一次,只是为了证明它可以用(这种)子查询来完成:
SELECT s.SiteId
, ( SELECT b.FeatureInstance_Id
FROM Blogs AS b
JOIN SiteFeatures sf
ON sf.FeatureInstanceId = b.FeatureInstance_id
WHERE sf.SiteId = s.SiteId
) AS BlogId
, ( SELECT pc.FeatureInstance_Id
FROM PageCollections AS pc
JOIN SiteFeatures sf
ON sf.FeatureInstanceId = pc.FeatureInstance_id
WHERE sf.SiteId = s.SiteId
) AS PagesId
, ( SELECT p.FeatureInstance_Id
FROM Portfolios AS p
JOIN SiteFeatures sf
ON sf.FeatureInstanceId = p.FeatureInstance_id
WHERE sf.SiteId = s.SiteId
) AS PortfolioId
FROM Sites AS s
答案 3 :(得分:1)
由于您使用的是SQL Server 2008
,因此以下是使用 CROSS APPLY 的一种可能选项,可能对您有用。它可能不是这里最好看的选择。我只是试了一下。
SELECT SFR.SiteId
, BLG.FeatureInstance_Id AS BlogId
, PFL.FeatureInstance_Id AS PortfolioId
, PGC.FeatureInstance_Id AS PagesId
FROM dbo.SiteFeatures SFR
CROSS APPLY (
SELECT
TOP 1 FeatureInstance_Id
FROM dbo.Blogs BLG
WHERE BLG.FeatureInstance_Id = SFR.FeatureInstanceId
) BLG
CROSS APPLY (
SELECT
TOP 1 FeatureInstance_Id
FROM dbo.PortFolios PFL
WHERE PFL.FeatureInstance_Id = SFR.FeatureInstanceId
) PFL
CROSS APPLY (
SELECT
TOP 1 FeatureInstance_Id
FROM dbo.PageCollections PGC
WHERE PGC.FeatureInstance_Id = SFR.FeatureInstanceId
) PGC