我有三张桌子
表类别
CategoryID Category
1 Climate
2 Area
表类别详细信息
DetailID CategoryID Desc
1 1 Hot
2 1 Cold
3 2 Area1
表类别详细信息
PK AnotherFK CategoryDetailID
1 1 1
2 1 1
3 1 2
4 2 1
这里AnotherFK是引用另一个表的外键。在记录1和2中存在重复,但是AnotherFK 1引用了CategoryDetailID 1和2,其categoryID为1,这是不正确的
所以从上面的表格 这个结果从以上三个表中有效
PK AnotherFK CategoryID DetailID Desc
1 1 1 1 Hot
2 1 1 1 Hot
但低于结果无效
PK AnotherFK CategoryID DetailID Desc
2 1 1 1 Hot
3 1 1 2 Cold
我不能将相同的AnotherFK放在两个具有相同CategoryID的不同DetailID中。我可以通过在CategoryDetailValues表中引入CategoryID并创建唯一约束来消除这一点,但我不允许这样做。
现在我的目标是在CategoryDetailValues表中查找具有与相同CategoryID相关联的不同DetailID的所有记录。这样我就可以删除它们了。
尝试在SQL Server 2012中实现此目的。
答案 0 :(得分:0)
如果您的目标是突出显示具有相同CategoryID但不同的DetailID的所有AnotherFK案例,则以下应该执行此操作(伪代码):
SELECT * FROM (SELECT AnotherFK, ROW_NUMBER() OVER
(ORDER BY AnotherFK, CategoryID) AS rn FROM #myTable) AS a
WHERE rn > 1
示例代码:
CREATE TABLE #myTable
(
AnotherFK int
, CategoryID int
, DetailID int
) ;
INSERT INTO #myTable (
AnotherFK
, CategoryID
, DetailID
)
VALUES (1, 1, 1)
, (1, 1, 2);
SELECT * FROM (SELECT AnotherFK, ROW_NUMBER() OVER (ORDER BY AnotherFK, CategoryID) AS rn FROM #myTable) AS a
WHERE rn > 1
DROP TABLE #myTable
如果这不是你想要的,请详细说明
答案 1 :(得分:0)
我认为你可以使用这样的东西:
创建样本表的脚本:
CREATE TABLE mytable(
PK INTEGER NOT NULL PRIMARY KEY
,AnotherFK INTEGER NOT NULL
,CategoryDetailID INTEGER NOT NULL
);
INSERT INTO mytable(PK,AnotherFK,CategoryDetailID) VALUES (1,1,1);
INSERT INTO mytable(PK,AnotherFK,CategoryDetailID) VALUES (2,1,1);
INSERT INTO mytable(PK,AnotherFK,CategoryDetailID) VALUES (3,1,2);
INSERT INTO mytable(PK,AnotherFK,CategoryDetailID) VALUES (4,2,1);
INSERT INTO mytable(PK,AnotherFK,CategoryDetailID) VALUES (5,1,3);
INSERT INTO mytable(PK,AnotherFK,CategoryDetailID) VALUES (6,1,3);
INSERT INTO mytable(PK,AnotherFK,CategoryDetailID) VALUES (7,1,3);
CREATE TABLE mytable2(
DetailID INTEGER NOT NULL
,CategoryID INTEGER NOT NULL
,Descr VARCHAR(5) NOT NULL
);
查询显示“可疑”记录(我认为你必须决定删除哪些记录......):
SELECT * FROM (
SELECT * ,COUNT(*) OVER (PARTITION BY CategoryID, ANotherFK) AS X
, COUNT(*) OVER (PARTITION BY CategoryID, DetailID, ANotherFK) AS X1
FROM mytable A
INNER JOIN mytable2 B ON A.CategoryDetailID= B.DetailID
)C
WHERE X-X1 >0
输出:
+--+----+-----------+------------------+----------+------------+-------+---+----+
| | PK | AnotherFK | CategoryDetailID | DetailID | CategoryID | Descr | X | X1 |
+--+----+-----------+------------------+----------+------------+-------+---+----+
| | 1 | 1 | 1 | 1 | 1 | Hot | 3 | 2 |
| | 2 | 1 | 1 | 1 | 1 | Hot | 3 | 2 |
| | 3 | 1 | 2 | 2 | 1 | Cold | 3 | 1 |
+--+----+-----------+------------------+----------+------------+-------+---+----+
答案 2 :(得分:0)
此查询将在Categorydetail中查找具有重复DetailID的记录。比加入表格为您提供详细信息。您仍然可以决定删除哪些记录。
select *
from(
Select CategoryID
from CategoryDetail
group by CategoryID
having count(DetailID)>1)aggr
join CategoryDetail c on aggr.CategoryID = c.CategoryID
join CategoryDetailValues v on c.CategoryDetailID = v.CategoryDetailID
答案 3 :(得分:0)
你想要每个AnotherFK和Category一个值。所以第三个表应该有一个复合键:
对AnotherFK,CategoryID具有唯一约束,并且都构建了CategoryDetail(CategoryID,DetailID)的外键。
为了首先清理数据,你必须寻找含糊之处:
select AnotherFK, CategoryID, DetailID
from
(
select
cdv.AnotherFK, cd.CategoryID, cdv.DetailID,
count(distinct cd.DetailID) over (partition by cdv.AnotherFK, cd.CategoryID) as cnt
from CategoryDetailValues cdv
join CategoryDetail cd on cd.DetailID = cdv.CategoryDetailID
)
where cnt > 1
order by AnotherFK, CategoryID, DetailID
答案 4 :(得分:0)
您可以尝试以下假设的解决方案:within CDV table, for every [AnotherFK] value (ex. 1) should be displayed only those rows with the minimum [CategoryDetailID] (ex. 1)
SELECT *
FROM (
SELECT cdv.PK, cdv.AnotherFK, cd.CategoryID, cd.[Desc],
Rnk = DENSE_RANK() OVER(PARTITION BY cdv.AnotherFK ORDER BY cdv.CategoryDetailID)
FROM dbo.CategoryDetailValues cdv
JOIN dbo.CategoryDetail cd ON cd.DetailID = cdv.DetailID
WHERE cdv.AnotherFK = 1
) x
WHERE x.Rnk = 1