SQL : Create a full record from 2 tables

ChPortos

I've got a DB structure as is (simplified to maximum for understanding concern):

Table "entry" ("id" integer primary key)
Table "fields" ("name" varchar primary key, and others)
Table "entry_fields" ("entryid" integer primary key, "name" varchar primary key, "value")

I would like to get, for a given "entry.id", the detail of this entry, ie. all the "entry_fields" linked to this entry, in a single SQL query.

An example would be better perhaps:

"fields":

"result"
"output"
"code"
"command"

"entry" contains:

id : 842
id : 850

"entry_fields" contains:

entryid : 842, name : "result", value : "ok"
entryid : 842, name : "output", value : "this is an output"
entryid : 842, name : "code", value : "42"
entryid : 850, name : "result", value : "ko"
entryid : 850, name : "command", value : "print ko"

The wanted output would be:

| id  | command    | output               | code | result |
| 842 | NULL       | "this is an output"  | 42   | ok     |
| 850 | "print ko" | NULL                 | NULL | ko     |

The aim is to be able to add a "field" without changing anything to "entry" table structure

I tried something like:

SELECT e.*, (SELECT name FROM fields) FROM entry AS e

but Postgres complains:

ERROR: more than one row returned by a subquery used as an expression

Hope someone can help me!

Erwin Brandstetter

Solution as requested

While stuck with this unfortunate design, the fastest query would be with crosstab(), provided by the additional module tablefunc. Ample details in this related answer:

For the question asked:

SELECT * FROM crosstab(
      $$SELECT e.id, ef.name, ef.value
       FROM   entry             e
       LEFT   JOIN entry_fields ef
              ON ef.entryid = e.id
             AND ef.name = ANY ('{result,output,code,command}'::text[])
       ORDER  BY 1, 2$$

     ,$$SELECT unnest('{result,output,code,command}'::text[])$$
   ) AS ct (id int, result text, output text, code text, command text);

Database design

If you don't have a huge number of different fields, it will be much simpler and more efficient to merge all three tables into one simple table:

CREATE TABLE entry (
   entry_id serial PRIMARY KEY
  ,field1   text
  ,field2   text
  , ... more fields
);

Fields without values can be NULL. NULL storage is very cheap (basically 1 bit per column in the NULL bitmap):

Even if you have hundreds of different columns, and only few are filled per entry, this will still use much less disk space.

You query becomes trivial:

SELECT entry_id, result, output, code, command
FROM   enty;

If you have too many columns1, and that's not just a misguided design (often, this can be folded into much fewer columns), consider the data types hstore or json / jsonb (in Postgres 9.4) for EAV storage.

1 Per Postgres "About" page:

Maximum Columns per Table   250 - 1600 depending on column types

Consider this related answer with alternatives:

And this question about typical use cases / problems of EAV structures on dba.SE:

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

SELECT query from 2 tables

来自分类Dev

在哪里可以找到phpMyAdmin的create_tables.sql?

来自分类Dev

Create if record does not exist

来自分类Dev

SQL Server renames tables

来自分类Dev

将CASE查询的SQL转换为Yii2 Active Record

来自分类Dev

自学问题mysql,How to use 2 table to create a 3rd table that uses the information on the original 2 tables

来自分类Dev

Entity Framework 6 Database First Approach Not Creating All Tables From SQL Server

来自分类Dev

Active Record - 转换 SQL 查询

来自分类Dev

SQL SELECT * FROM 2 个表

来自分类Dev

Update 2 tables

来自分类Dev

Create a waveform of the full track with Web Audio API

来自分类Dev

I am trying to select data from 2 mysql tables into 1 query

来自分类Dev

ActiveRecord中的create / create_record在哪里?

来自分类Dev

Application creates the database, but doesn't create the tables

来自分类Dev

Select count from four tables

来自分类Dev

Hive SQL Full Outer Join with Where子句

来自分类Dev

让 Django Tables2 工作

来自分类Dev

SQL,如果Record等于它之前的记录

来自分类Dev

How to use bootstrap css tables to display data from MySQL tables?

来自分类Dev

how to take a single record from an arraylist in mongodb

来自分类Dev

Select a specific staging record from sybase table

来自分类Dev

执行full_clean的Model.objects.create等效项?

来自分类Dev

执行full_clean的Model.objects.create等效项?

来自分类Dev

如何在dplyr中获取full_join来保留data.tables?

来自分类Dev

MySQL SELECT from two tables with COUNT

来自分类Dev

从查询PERFORM 1进入temp from master_balance,其中externalkey ='jknfl12j3'和tenant_record_id ='2'以进行更新; 1

来自分类Dev

SQL Server matching all rows from Table1 with all rows from Table2

来自分类Dev

MySQL Query 2 Tables Join列旁边

来自分类Dev

Django Tables 2中的链接列

Related 相关文章

  1. 1

    SELECT query from 2 tables

  2. 2

    在哪里可以找到phpMyAdmin的create_tables.sql?

  3. 3

    Create if record does not exist

  4. 4

    SQL Server renames tables

  5. 5

    将CASE查询的SQL转换为Yii2 Active Record

  6. 6

    自学问题mysql,How to use 2 table to create a 3rd table that uses the information on the original 2 tables

  7. 7

    Entity Framework 6 Database First Approach Not Creating All Tables From SQL Server

  8. 8

    Active Record - 转换 SQL 查询

  9. 9

    SQL SELECT * FROM 2 个表

  10. 10

    Update 2 tables

  11. 11

    Create a waveform of the full track with Web Audio API

  12. 12

    I am trying to select data from 2 mysql tables into 1 query

  13. 13

    ActiveRecord中的create / create_record在哪里?

  14. 14

    Application creates the database, but doesn't create the tables

  15. 15

    Select count from four tables

  16. 16

    Hive SQL Full Outer Join with Where子句

  17. 17

    让 Django Tables2 工作

  18. 18

    SQL,如果Record等于它之前的记录

  19. 19

    How to use bootstrap css tables to display data from MySQL tables?

  20. 20

    how to take a single record from an arraylist in mongodb

  21. 21

    Select a specific staging record from sybase table

  22. 22

    执行full_clean的Model.objects.create等效项?

  23. 23

    执行full_clean的Model.objects.create等效项?

  24. 24

    如何在dplyr中获取full_join来保留data.tables?

  25. 25

    MySQL SELECT from two tables with COUNT

  26. 26

    从查询PERFORM 1进入temp from master_balance,其中externalkey ='jknfl12j3'和tenant_record_id ='2'以进行更新; 1

  27. 27

    SQL Server matching all rows from Table1 with all rows from Table2

  28. 28

    MySQL Query 2 Tables Join列旁边

  29. 29

    Django Tables 2中的链接列

热门标签

归档