比较sql查询中的子记录

时间:2016-10-27 09:43:58

标签: sql-server tsql

我有一个关于如何比较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))

每个父记录可以有多个子记录,我想知道的是哪些父表在value1value2中具有相同值的子表,我们忽略value3

我可以通过为父表添加一个附加字段来做,然后遍历子记录并将value1value2的值添加到此附加字段。

[开始编辑]
例如,我在子表中有以下数据 (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个。

我根本不知道如何处理这个问题,所以我希望有人可以帮助我。如果我的问题不够明确,请告诉我。谢谢你的回答和时间。

2 个答案:

答案 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;