PostgreSQL:如何获取没有主地址的所有记录(用户)?

时间:2019-04-29 12:51:01

标签: sql postgresql

为有效地解释问题,以下是模式和查询示例:


架构(PostgreSQL v9.4)

module.exports.handler = (event, context, callback) => {
  const buffer = getAnswer();
  // This is approx 2.1 MB buffer size
  console.log(`Buffer size ${buffer.byteLength}`);

  const response = {
    headers: {
      'Content-Type': 'application/json',
    },
    isBase64Encoded: false,
    statusCode: 200,
    statusDescription: '200 OK',
    body: JSON.stringify(buffer),
  };
  // Here  size becomes more than 7.5 MB ,I am not sure how it happens
  console.log('This becomes 7.5 MB size', Buffer.byteLength(JSON.stringify(response)), 'bytes');
  context.succeed(response);// Gives error because it exceeds more than 6MB lambda response limit
};

查询

CREATE TABLE users (
  id serial,
  username VARCHAR(25) NOT NULL,
  PRIMARY KEY (id)
);

INSERT INTO USERS (username) VALUES 
('user 1'), ('user 2'), ('user 3'), ('user 4');

CREATE TABLE addresses (
  id serial,
  user_id INT NOT NULL,
  street VARCHAR(30) NOT NULL,
  is_primary BOOLEAN NOT NULL DEFAULT FALSE,
  PRIMARY KEY (id),
  CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES users (id)
);

INSERT INTO addresses (user_id, street, is_primary) VALUES
(1, 'address 1', false), (1, 'address 2', false), (1, 'address 3', false),
(2, 'address 4', false), (2, 'address 5', false), (2, 'address 6', false),
(3, 'address 7', false), (3, 'address 8', false), (3, 'address 9', true),
(4, 'address 10', false), (4, 'address 11', true), (4, 'address 12', false);
select * from addresses;

预期结果

Id喜欢在下面获取这些记录:


| id  | user_id | street     | is_primary |
| --- | ------- | ---------- | ---------- |
| 1   | 1       | address 1  | false      |
| 2   | 1       | address 2  | false      |
| 3   | 1       | address 3  | false      |
| 4   | 2       | address 4  | false      |
| 5   | 2       | address 5  | false      |
| 6   | 2       | address 6  | false      |
| 7   | 3       | address 7  | false      |
| 8   | 3       | address 8  | false      |
| 9   | 3       | address 9  | true       |
| 10  | 4       | address 10 | false      |
| 11  | 4       | address 11 | true       |
| 12  | 4       | address 12 | false      |


到目前为止我尝试过的事情

使用 | id | user_id | street | is_primary | | --- | ------- | ---------- | ---------- | | 1 | 1 | address 1 | false | | 2 | 1 | address 2 | false | | 3 | 1 | address 3 | false | | 4 | 2 | address 4 | false | | 5 | 2 | address 5 | false | | 6 | 2 | address 6 | false | ALL子句的示例,坦白地说,我对SQL脚本的了解非常有限,因此我无法弄清楚如何获得正确的结果。

3 个答案:

答案 0 :(得分:2)

您可以使用EXISTS和相关的子查询来搜索用户的主要地址。

SELECT a1.*
       FROM addresses a1
       WHERE NOT EXISTS (SELECT *
                                FROM addresses a2
                                WHERE a2.user_id = a1.user_id
                                      AND is_primary);

答案 1 :(得分:1)

我要注意,您可以使用窗口功能来做到这一点:

select a.*
from (select a.*,
             bool_or(a.is_primary) over (partition by a.user_id) as any_primary
      from addresses a
     ) a
where not any_primary;

有关BOOL_OR函数的更多信息,请参见Postgres documentation

答案 2 :(得分:1)

您可以尝试这样查询:

select * from addresses 
where is_primary = false 
  and user_id not in (select user_id from addresses where is_primary = true);