我正在尝试使用master-detail类型结构查询预先存在的数据模型,如下所示:
Master
-----
MasterId (PK)
Description
Detail
-----
DetailId (PK)
MasterId (FK)
DetailCategoryId (FK)
Description
还有一系列详细记录,MasterId为-1,表示每个详细信息类别的默认值。因此,如果对于指定的类别,Master没有Detail,则应该检索默认值。
我已经设法通过几种不同的方式为给定的主记录做到了这一点,但到目前为止我提出的解决方案通常需要我,以确定'指定'的细节然后与一组缺少默认值。
我的问题是如何为所有/多个主记录执行此操作?
(这是一个现有的数据模型,我正在查询报告目的。我可能会做一些小修改,但没有机会进行全面的重新设计,因此问题实际上是'我该如何处理这个?'而不是“我该如何重新塑造这个?”)
答案 0 :(得分:1)
我认为这会奏效。您只需将15替换为任何类别。
SELECT
m.MasterId,ISNULL(d.DetailId,dflt.DetailId)
FROM Master m
LEFT JOIN Detail d ON d.masterid=m.masterid and d.DetailCategoryId=15
LEFT JOIN Detail dflt on dflt.masterid=-1 and d.DetailCategoryId=15
答案 1 :(得分:0)
试试这个:
WITH CTE AS (
SELECT M.MasterId, M.Description, D.DetailId
FROM Master M
LEFT JOIN Detail D ON M.MasterId = D.MasterId AND D.DetailCategoryId = @CatId
)
SELECT MasterId, Description, DetailId
FROM CTE
WHERE DetailId IS NOT NULL
UNION
SELECT CTE.MasterId, CTE.Description, D.DetailId
FROM CTE
JOIN Detail D ON D.MasterId = -1 AND D.DetailCategoryId = @CatId
WHERE CTE.DetailId IS NULL
以下是用于测试的SQL Fiddle。
祝你好运。答案 2 :(得分:0)
第一个解决方案:
DECLARE @MasterID INT;
SET @MasterID=123;
SELECT d.DetailID, d.DetailCategoryID, d.Description
FROM Detail d
WHERE d.MasterID=@MasterID;
IF @@ROWCOUNT=0 -- If no rows then fetch default rows
BEGIN
SELECT d.DetailID, d.DetailCategoryID, d.Description
FROM Detail d
WHERE d.MasterID=-1;
END;
第二个解决方案:
SELECT *
FROM (
SELECT *, DENSE_RANK() OVER(ORDER BY x.MasterID DESC) AS Rnk
FROM (
SELECT d.MasterID, d.DetailID, d.DetailCategoryID, d.Description
FROM Detail d
WHERE d.MasterID=@MasterID
UNION ALL
SELECT d.MasterID, d.DetailID, d.DetailCategoryID, d.Description
FROM Detail d
WHERE d.MasterID=-1
) x
) y
WHERE y.MasterID=-1 AND y.Rnk=1
OR y.MasterID>0;
注意:最后一个解决方案假设所有MasterID
非默认值都大于0(MasterID>0
)。