我有一个关于如何比较MS SQL数据库中的子记录的问题。 在我的例子中,我有两个表:
parent(Id int,name nvarchar(10))
child(Id int, ParentId int(fk to parent.id),value1 nvarchar(10),value2 nvarchar(10),value3 nvarchar(10))
每个父记录可以有多个子记录,我想知道的是哪些父表在value1
和value2
中具有相同值的子表,我们忽略value3
我可以通过为父表添加一个附加字段来做,然后遍历子记录并将value1
和value2
的值添加到此附加字段。
[开始编辑]
例如,我在子表中有以下数据
(id,parentid,val1,val2,val3
1,2,为test1,test2的,东西
2,2,TEST0,TEST4,东西
3,3,为test1,test2的,somethingelse
4,3,TEST0,TEST4,somethingelse
5,4,testx,TEST2,somethingelse
6,4,testx,TEST4,somethingelse
我想知道parentID 2和3的记录对val1和val2具有相同的记录
[结束编辑]
我还想知道,如果5个儿童记录中有4个具有相同的值,或者4个中有3个。
我根本不知道如何处理这个问题,所以我希望有人可以帮助我。如果我的问题不够明确,请告诉我。谢谢你的回答和时间。
答案 0 :(得分:0)
如果您只需要表格,并且不希望循环遍历所有外键。然后是第一个问题:
SELECT
DISTINCT parentID
FROM
childTable ct
WHERE
ISNULL(ct.value1, 0) = ISNULL(ct.value2, 0)
如果要查看所有字段父表
SELECT
DISTINCT pt.*
FROM
childTable ct
JOIN ParentTable pt
ON pt.Id = ct.ParentID
WHERE
ISNULL(ct.value1, 0) = ISNULL(ct.value2, 0)
第二个问题:
SELECT
*
FROM
(
SELECT
COUNT(ct.id) countChildID,
ct.ParentID
FROM
childTable ct
GROUP BY
ct.ParentID
) S
LEFT JOIN (
SELECT
COUNT(ct.ID) countChildID,
parentID
FROM
childTable ct
WHERE
ISNULL(ct.value1, 0) = ISNULL(ct.value2, 0)
GROUP BY
ParentID
) N
ON S.ParentID = N.ParentId
WHERE S.countChildID = 5 AND N.countChildID = 3
对于MS SQL Server 2012或更高版本,您可以使用COUNT OVER(Partition BY)
答案 1 :(得分:0)
您可以使用 COUNT(p.Id)OVER(PARTITION BY c.value1,c.value2)AS equals_count 计算每对value1和c.value2的ParentId。之后,您可以计算所有对的数量:
CREATE TABLE #parent (
Id INT
,NAME NVARCHAR(10)
)
CREATE TABLE #child (
Id INT
,ParentId INT
,value1 NVARCHAR(10)
,value2 NVARCHAR(10)
,value3 NVARCHAR(10)
)
INSERT INTO #parent
VALUES (
1
,'first'
)
,(
2
,'second'
),(
3
,'third'
);
INSERT INTO #child
VALUES (
1
,1
,'1'
,'1'
,'1'
)
,(
2
,1
,'2'
,'2'
,'2'
)
,(
3
,1
,'1'
,'2'
,'3'
)
,(
4
,1
,'1'
,'3'
,'4'
)
,(
5
,2
,'1'
,'2'
,'5'
)
,(
6
,2
,'1'
,'3'
,'5'
)
,(
7
,3
,'1'
,'3'
,'5'
);
WITH cte
AS (
SELECT p.Id AS ParentId
,p.NAME
,c.Id AS ChildId
,c.value1
,c.value2
,c.value3
,COUNT(p.Id) OVER (PARTITION BY c.value1, c.value2) AS equals_count
,COUNT(*) OVER() AS all_count
FROM #parent AS p
LEFT JOIN #child AS c ON p.Id = c.ParentId
)
SELECT ParentId
,NAME
,ChildId
,value1
,value2
,value3
,equals_count
,all_count
,(SELECT COUNT(*) FROM cte WHERE equals_count > 1 ) AS repeated_count
FROM cte
ORDER BY value1, value2
DROP TABLE #parent;
DROP TABLE #child;