如何限制加入查询?

时间:2013-02-23 00:12:46

标签: mysql phpmyadmin

我正在尝试导出每个客户只有一个地址簿条目的客户列表。

SELECT c.customers_id, c.customers_firstname, c.customers_lastname,
ab.address_book_id, ab.customers_id, ab.entry_company, ab.entry_firstname, ab.entry_lastname, ab.entry_street_address
FROM customers c
INNER JOIN address_book ab
ON c.customers_id=ab.customers_id
WHERE 1=1
ORDER BY c.customers_id ASC

我做错了什么?


编辑:我有超过1个地址簿条目,因为有些客户有2个已保存的地址。但我只需要一个出口。

4 个答案:

答案 0 :(得分:0)

创建一个只返回一个客户ID和一个address_book_id的表,就像我在下面做的那样

SELECT c.customers_id, c.customers_firstname, c.customers_lastname,
ab.address_book_id, ab.customers_id, ab.entry_company, ab.entry_firstname,     ab.entry_lastname, ab.entry_street_address
FROM customers c
 INNER JOIN address_book ab ON c.customers_id=ab.customers_id
 INNER JOIN
 (SELECT customers_id, MAX(address_book_id) AS AddressBookID
  FROM address_book
  GROUP BY customers_id) AS NewAddressBook ON c.customers_id = NewAddressBook.customers_id AND ab.address_book_id = NewAddressBook.AddressBookID
ORDER BY c.customers_id ASC

答案 1 :(得分:0)

我认为这应该有效 - 它返回MIN(address_book_id):

SELECT c.customers_id, c.customers_firstname, c.customers_lastname,
    ab.address_book_id, ab.customers_id, ab.entry_company, ab.entry_firstname, ab.entry_lastname,   ab.entry_street_address
FROM customers c
    INNER JOIN address_book ab
        ON c.customers_id=ab.customers_id
    INNER JOIN (
        SELECT MIN(address_book_id) min_address_book_id, customers_id
        FROM address_book 
        GROUP BY customers_id
    ) m ON ab.customers_id = m.customers_id AND 
        ab.address_book_id = m.min_address_book_id
ORDER BY c.customers_id ASC

答案 2 :(得分:0)

在MySQL中,您可以执行以下操作:

SELECT c.customers_id, c.customers_firstname, c.customers_lastname,
ab.address_book_id, ab.customers_id, ab.entry_company, ab.entry_firstname, ab.entry_lastname, ab.entry_street_address
FROM customers c
INNER JOIN address_book ab
ON c.customers_id=ab.customers_id
group by c.customers_id
ORDER BY c.customers_id ASC

这会为所有其他字段提取任意值。对于来自customer的字段,值很好,因为它们在所有行上都相同。对于address_book中的字段,会选择任意值。

理论上,这可以混合来自不同行的值。虽然这在实践中没有发生,但是没有保证。因此,这是使用MySQL中名为Hidden Columns的功能执行所需操作的一种方法。

答案 3 :(得分:0)

<强>更新

由于您要检索哪个address_book条目无关紧要,因此此查询将获取最大address_book_id值的那些:

SELECT c.customers_id, 
       c.customers_firstname, 
       c.customers_lastname,
       ab.address_book_id,
       ab.customers_id, 
       ab.entry_company, 
       ab.entry_firstname,
       ab.entry_lastname,
       ab.entry_street_address 
  FROM customers c LEFT JOIN 
       address_book ab ON c.customers_id=ab.customers_id AND
       ab.address_book_id = (SELECT MAX(address_book_id) 
                              FROM address_book 
                             WHERE customers_id = c.customers_id)
 ORDER BY c.customers_id;

理论上,您可以让客户没有相关的地址簿条目。 LEFT JOIN将允许您拉动它们。如果您不希望出现此行为,只需将LEFT JOIN更改为INNER JOIN

此处有效sqlfiddle

原始答案

这是我的第一个答案,它可以在MySql中运行,尽管它可以从不同的行中获取任意值。请参阅@Gordon Linoff的回答中的解释。

SELECT c.customers_id, 
       c.customers_firstname, 
       c.customers_lastname,
       MAX(ab.address_book_id),
       MAX(ab.customers_id), 
       MAX(ab.entry_company), 
       MAX(ab.entry_firstname),
       MAX(ab.entry_lastname),
       MAX(ab.entry_street_address)
FROM customers c INNER JOIN 
     address_book ON c.customers_id=ab.customers_id
GROUP BY c.customers_id, c.customers_firstname, c.customers_lastname,
ORDER BY c.customers_id