【问题标题】:Sql distinct selective row after a join question连接问题后的 Sql distinct 选择性行
【发布时间】:2010-11-20 10:33:11
【问题描述】:

假设我有 2 张表 Customer 和 Books。

Table Books 可以有多个与 Customer 中的行相关的行。

例如: 客户 John Doe 的 ID 为 1000。 Table Books 有 2 行,其中 member_id 列为 1000 (John Doe)。

这 2 行是相同的,除了其中一个字段(书名)为空。另一行有一个标题值。

问题: 我如何查询这个以便我检索具有有效标题值的行,但是,如果两个标题值都是空的,那么它只返回一行?

我当然希望这是有道理的。

【问题讨论】:

    标签: sql join distinct


    【解决方案1】:

    您应该能够使用不同的运算符:

    SELECT DISTINCT Customers.member_id, Books.book_title
    FROM Customers
    INNER JOIN Books ON Customers.member_id = Books.member_id
    

    如果这不能正常工作,您可以使用内部选择:

    SELECT DISTINCT *
    FROM (SELECT Customers.member_id, Books.book_title
          FROM Customers
          INNER JOIN Books ON Customers.member_id = Books.member_id) As newTable
    

    另外,如果这是一个经常使用的查询,我会避免使用 UNION,因为已知它们存在性能问题。

    回应编辑:

    SELECT Customers.member_id, Customer_Info.Name, ISNULL(newTable.book_title, '')
    FROM Customers
    INNER JOIN Customer_Info
    LEFT JOIN (SELECT DISTINCT member_id, book_title FROM Books) newTable
        ON newTable.member_ID = Customers.member_id
    

    这应该返回与客户关联的所有书籍(但每个标题只有一次,如果没有找到书籍,则它将返回一个空字符串。)如果这不能回答问题,请提供有关表格的一些附加信息以及您想要的结果示例,我会更新。

    好的,现在我想我知道你在找什么了:

    这是一个可能的查询,基于您使用提供的表格的原始问题。但是,如果客户设置了两个不同的电子邮件地址,它将不起作用;在这种情况下,您可以添加一个 TOP(1) 以确保只有一个结果,但您不知道它是否是“正确的结果”。

    SELECT Customers.member_id, Office.Office_Name, ISNULL(newTable.email, '')
    FROM Customers
    INNER JOIN Office
    LEFT JOIN (SELECT DISTINCT member_id, email 
               FROM Books 
               WHERE email IS NOT NULL AND email <> '') newTable
        ON newTable.member_ID = Customers.member_id
    

    这是基于您提供的数据和示例输出的另一个查询。

    SELECT Member_Name, Email
    FROM thridTable
    WHERE Member_Name = @SomeInputParameter
    

    我不确定您的示例数据有多具有代表性,但您为什么要将成员名称存储在多个表中?这在未来肯定会令人头疼。

    【讨论】:

    • 好的,让我把这把扳手扔进去。我无法区分的原因是有 3 张桌子。第三个表是 CutomerInfo。所以有两个 JOINS(Customer-CustomerInfo 和 Customer-Books)。返回的行包含来自 Customer、CustomerInfo 和 Books 的字段。我可以返回所有书籍或带有标题的书籍(其中 book.title '')。也许我需要检查第一个查询是否返回某些内容,如果没有,则在删除 (where book.title '') 的情况下执行第二个查询?
    • 谢谢jellmonk。我不得不调整你的新回复 sn-p 因为它抱怨 member_id (在最后一行)。我在周围按摩。如果它有效,我会告诉你。如果没有,我会提供表格。
    • 似乎它不起作用,因为.... LEFT JOIN (SELECT DISTINCT member_id, book_title FROM Books) newTable 不返回单行,它仍然返回多行(因为 book_title 每行不同)。
    • 但这对布莱斯仍然不起作用,因为他没有定义任何电子邮件。
    【解决方案2】:

    如果我理解您的意思,此查询将返回所有书名非空的记录以及所有没有有效书名的客户记录,有效被定义为书名非空的书名。

    SELECT c.id, c.name, b.title
    FROM customer c
    JOIN book b ON c.id = b.customer_id
    WHERE b.title IS NOT NULL
    UNION ALL
    SELECT c.id, c.name, NULL
    FROM customer c
    WHERE NOT EXISTS (SELECT title FROM book b WHERE customer_id = c.id AND title IS NOT NULL)
    

    【讨论】:

      【解决方案3】:

      你可以使用:

      isnull(BOOKTITLE,'') = '' 
      

      在那个领域和一个不同的,它应该给出一个结果

      【讨论】:

        猜你喜欢
        • 2012-10-17
        • 2021-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-01
        相关资源
        最近更新 更多