简体   繁体   English

postgresql作为json结果一对多,如何过滤?

[英]postgresql one to many as json result, how to filter?

I have a simple db structure with a one to many relationship 我有一个简单的数据库结构,具有一对多关系

CREATE TABLE customer (
  id                              SERIAL PRIMARY KEY,
  email                           TEXT,
  first_name                      TEXT,
  last_name                       TEXT
);

CREATE TABLE customer_address (
  id              SERIAL PRIMARY KEY,
  customer_id     INTEGER                NOT NULL,
  street_name     TEXT                   NOT NULL,
  street_number   TEXT                   NOT NULL,
  zip_code        TEXT                   NOT NULL,
  city            TEXT                   NOT NULL
);

For my application I want to return each customer with all its addresses as one row, whereby I encapsulate all the addresses in a json array. 对于我的应用程序,我想返回每个客户及其所有地址为一行,从而将所有地址封装在一个json数组中。 This is done like this: 这样做是这样的:

SELECT customer.*, 
       addresses 
FROM   customer 
       left join (SELECT 
Array_to_json(Array_agg( 
Json_build_object('id', address.id, 'street_name', address.street_name, 'street_number', address.street_number, 'zip_code', address.zip_code, 'city', address.city))) AS addresses,
address.customer_id 
AS customer_id 
 FROM   customer_address AS address 
 GROUP  BY address.customer_id) addresses 
       ON addresses.customer_id = customer.id 
join customer_address 
  ON customer_address.customer_id = customer.id 

This works fine and gives me a resultset with for each result an element called addresses containing a JSON array of all the customer's addresses. 这可以正常工作,并为我提供了一个结果集,其中每个结果都有一个名为addresses的元素,其中包含所有客户地址的JSON数组。

Now I would like to select all customers (with all of their addresses) whose street_name is like a certain search term. 现在,我想选择street_name就像某个搜索词的所有客户(及其所有地址)。 And I can't get it to work. 而且我无法正常工作。 How can I select full records including all addresses inlined when one address has a street name containing a certain value (matched with an ILIKE ) ? 当一个地址的街道名称包含某个值(与ILIKE匹配)时,如何选择包括所有内联地址的完整记录?

I tried adding: WHERE customer_address.street_name LIKE 'Ro' , and while this works, if I replace this where statement with something completely different such as WHERE customer.id > 0 I get doubles in the result set 我尝试添加: WHERE customer_address.street_name LIKE 'Ro' ,并且这WHERE customer_address.street_name LIKE 'Ro' ,但是,如果我用完全不同的东西(例如WHERE customer.id > 0替换此where语句,则结果集中将有双

Here is an sql Fiddle to play around in: 这是一个可在其中玩耍的sql小提琴:

http://sqlfiddle.com/#!17/0e818/4 http://sqlfiddle.com/#!17/0e818/4

This join condition looks wrong: 此连接条件看起来是错误的:

JOIN customer_address ON customer_address.id = customer.id

Shouldn't it be 不是吗

JOIN customer_address ON customer_address.customer_id = customer.id

Here is the fiddle: http://sqlfiddle.com/#!17/2fff0/6 这是小提琴: http ://sqlfiddle.com/#!17/ 2fff0/6

Following the discussions on the original answer, here is the final solution that addresses the raised issues: 在讨论了原始答案之后,这是解决所提出问题的最终解决方案:

http://sqlfiddle.com/#!17/2fff0/25 http://sqlfiddle.com/#!17/2fff0/25

Does this cover your expected result? 这是否涵盖您的预期结果?

 SELECT customer.*,addresses FROM customer LEFT JOIN (SELECT array_to_json(array_agg(json_build_object('id',address.id,'street_name',address.street_name,'street_number',address.street_number,'zip_code',address.zip_code,'city',address.city))) AS addresses,address.customer_id AS customer_id FROM customer_address AS address GROUP BY address.customer_id) addresses ON addresses.customer_id = customer.id JOIN customer_address ON customer_address.id = customer.id WHERE customer_address.street_name LIKE 'Ro%' 
\nid | id | email | 电邮| first_name | first_name | last_name | last_name | addresses 地址                                                                                                                                                                                       \n-: | -:| :------------ | :------------ | :--------- | :--------- | :-------- | :-------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- :------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------------------------------\n 1 | 1 | john@test.com | john@test.com | John | 约翰| Doe | 美国能源部 [{"id" : 1, "street_name" : "Route", "street_number" : "222", "zip_code" : "9000", "city" : "NY"},{"id" : 2, "street_name" : "Ro", "street_number" : "444", "zip_code" : "9000", "city" : "LA"}] [{“ id”:1,“ street_name”:“ Route”,“ street_number”:“ 222”,“ zip_code”:“ 9000”,“ city”:“ NY”},{“ id”:2,“ street_name “:” Ro“,”街道编号“:” 444“,”邮政编码“:” 9000“,”城市“:” LA“}]\n

dbfiddle here dbfiddle 在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM