2015-06-19 1 views
2

Вот мои таблицы (в том числе только соответствующих столбцов)Не включайте выберите столбцы в группе

Table: carts 
address_id - integer 

Table: addresses 
name - varchar 
phone - varchar 

Table: orders 
order_number - integer (this is the foreign key for cart table) 

Я хочу, чтобы принести номер телефона клиентов, которые заказали только один раз, так что я построил следующий запрос

select addresses.phone 
from orders 
    inner join carts on orders.order_number = carts.id 
    inner join address on carts.address_id = addresses.id 
group by addresses.phone 
having count(orders.*) = 1; 

Это отлично работает! Но я также необходимо выбрать имя клиента & номер заказа, и я обновил выберите заявление

select addresses.phone, addresses.name, orders.order_number ... 

Теперь, Postgres призывает меня включить эти столбцы в GROUP BY пункте, но это не вернет мне желаемого результата.

Я попытался с помощью подзапроса, как после чего, кажется мне получить желаемый результат

select addresses.phone, (select ad.name from addresses ad where ad.phone = addresses.phone) ... 

Но использование подзапроса является единственным способом идти об этом? или есть ли более простой/оптимальный способ?

+0

Могли бы вы предоставить некоторые выборочные данные для того, чтобы воспроизвести ваши проблемы? У вас разные имена для одного и того же номера телефона и/или наоборот? В общем случае, если данные строгие, одновременное добавление столбцов к «SELECT» и «GROUP BY» должно быть прекрасным. Все остальные случаи, которые приходят мне на ум, не будут излечены вашим подзаголовком. Однако вы можете поместить свой первоначальный оператор в свой список: [SQL Fiddle] (http://sqlfiddle.com/#!15/0966a/1) – Abecee

+0

вы пытались использовать DISTINCT? –

+0

@SQL Fiddle: возможны разные имена для одного и того же номера телефона –

ответ

2

Вы можете добиться этого с window function, который не требует, чтобы все было группировать:

select * 
from (
    select addresses.phone, addresses.name, orders.order_number, 
     count(orders.order_number) over (partition by addresses.phone) as cnt 
    from orders 
    inner join carts on orders.order_number = carts.id 
    inner join address on carts.address_id = addresses.id 
) t 
where cnt = 1; 
+0

Sweet! Точно, что мне нужно :) –