【问题标题】:Do not include select columns in group by不要在分组依据中包含选择列
【发布时间】:2015-06-19 08:00:30
【问题描述】:

这是我的表格(仅包括相关列)

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) ...

但是使用子查询是解决这个问题的唯一方法吗?还是有更简单/最佳的方法?

【问题讨论】:

  • 您能否提供一些示例数据以重现您的麻烦?同一个电话号码是否有不同的名称或/反之亦然?一般来说,如果数据很严格,同时向SELECTGROUP BY 添加列应该没问题。我想到的所有其他情况都不会被您的子选择治愈。但是,您可以将您的初始声明放入您的列表中:SQL Fiddle
  • 您尝试过使用 DISTINCT 吗?
  • @SQL Fiddle:是的,同一个电话号码可以有不同的名字
  • @SQL Fiddle:你的问题实际上让我重新思考了我的数据库结构,我允许在同一个电话号码上使用多个名称的全部原因是允许用户拥有多个地址并且我在里面包含了名称地址表。也许我可以有一个用户表,其中存储姓名、电话号码和关联 has_many belongs_to 用户和地址表之间的关系。我认为我这样做时不应该面对这个问题
  • @Abecee 这就是我最终做的事情:)

标签: sql postgresql group-by subquery


【解决方案1】:

您可以使用 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;

【讨论】:

  • 甜蜜!正是我需要的:)
猜你喜欢
  • 1970-01-01
  • 2010-11-04
  • 1970-01-01
  • 1970-01-01
  • 2016-05-01
  • 1970-01-01
  • 2020-09-28
  • 1970-01-01
  • 2020-11-19
相关资源
最近更新 更多