代码之家  ›  专栏  ›  技术社区  ›  Jimmy

SQL子关系查询帮助

  •  0
  • Jimmy  · 技术社区  · 15 年前

    | Parent |  | Child  |
    |   id   |  |   id   |
    |        |  |parentID|
    |        |  |  date  |
    

    我正试图构造一个查询,以便得到所有有孩子的父母的记录,这些记录都在指定日期之前有日期。

    像这样的东西

    SELECT * FROM parent
    JOIN child on child.parentid = parent.id
    WHERE child.date <= '10/13/2010'
    

    但问题是,当我只想要日期早于指定日期的孩子的父母时,我得到的父母的孩子的日期早于指定日期,并且孩子的记录早于指定日期。

    有人对如何处理这个案子有什么建议吗?

    3 回复  |  直到 15 年前
        1
  •  2
  •   OMG Ponies    15 年前

    使用:

    SELECT p.*
      FROM PARENT p
     WHERE EXISTS(SELECT NULL
                    FROM CHILD c
                   WHERE c.parentid = p.id
                     AND c.date <= '2010-10-13')
       AND NOT EXISTS(SELECT NULL
                        FROM CHILD c
                       WHERE c.parentid = p.id
                         AND c.date > '2010-10-13')
    

    使用 如果不需要支持表中的信息,就不应该加入它。这是因为在这种情况下不止一个孩子会产生重复的父母记录。通过vs IN或EXISTS在JOIN和DISTINCT或GROUP之间进行权衡可能是公平的,但不必麻烦地正确处理重复的数据。

        2
  •  2
  •   Phil Hunt    15 年前
    SELECT
      *
    FROM
      Parent
    WHERE
      EXISTS (SELECT * FROM Child WHERE Child.ParentId = Parent.Id AND [date] <= '2010-10-13')
      AND
      NOT EXISTS (SELECT * FROM Child WHERE Child.ParentId = Parent.Id AND [date] > '2010-10-13')
    
        3
  •  0
  •   beach    15 年前

    我仔细阅读了你的问题并总结如下:

    • 我希望所有父母的孩子都在X日/之前有个约会

    见下面的代码。我们使用HAVING语句来确保孩子们在X之后没有日期。

    SELECT P.*
    FROM Parent P
    WHERE P.id IN
    (
        SELECT C.parentID
        FROM Child C
        GROUP BY C.parentID
        HAVING MAX(CASE WHEN date > '2010-10-13' THEN 1 ELSE 0 END) = 0
        /* do not return children that have a date after 2010-10-13 */
    )   
    

    (“date”被称为“mydate”,以避免必须转义保留字。)

    CREATE TABLE Parent (id INT PRIMARY KEY);
    CREATE TABLE Child (id INT IDENTITY PRIMARY KEY, parentID INT NOT NULL REFERENCES Parent(id), mydate DATE );
    
    INSERT INTO Parent VALUES (1);
    INSERT INTO Parent VALUES (2);
    INSERT INTO Parent VALUES (3);
    INSERT INTO Parent VALUES (4);
    
    INSERT INTO Child (parentID, mydate) VALUES (1,'2010-10-11')
    INSERT INTO Child (parentID, mydate) VALUES (1,'2010-10-12')
    INSERT INTO Child (parentID, mydate) VALUES (1,'2010-10-13')
    
    INSERT INTO Child (parentID, mydate) VALUES (2,'2010-10-12')
    INSERT INTO Child (parentID, mydate) VALUES (2,'2010-10-13')
    INSERT INTO Child (parentID, mydate) VALUES (2,'2010-10-14')
    
    INSERT INTO Child (parentID, mydate) VALUES (3,'2010-10-14')
    INSERT INTO Child (parentID, mydate) VALUES (3,'2010-10-15')
    INSERT INTO Child (parentID, mydate) VALUES (3,'2010-10-16')