考虑下表
Device
--------
id
name
type
--------
components
--------
id INT
type VARCHAR
--------
Manufacturers
-------------
id INT
name VARCHAR
country VARCHAR
-------------
Device_components
-----------------
deviceid REFERENCES Devices(id)
componentid REFERENCES Components(id)
-----------------
Component_Manufacturers
-----------------------
componentid REFERENCES Components(id)
manufacturerid REFERENCES Manufacturers(id)
-----------------------
Run Code Online (Sandbox Code Playgroud)
我想查询数据库以返回如下内容:
{
"id": 1,
"name": "phone",
"components": [
{
"id": 1,
"type": "screen",
"manufacturers": [
{
"id": 1,
"name": "a",
"country": "Germany"
}
]
},
{
"id": 2,
"type": "keyboard",
"manufacturers": [
{
"id": 1,
"name": "a",
"country": "UK" …Run Code Online (Sandbox Code Playgroud) 我有一个非常简单的 JSON 表,其中填充了一些示例数据:
CREATE TABLE jsonthings(d JSONB NOT NULL);
INSERT INTO jsonthings VALUES ('{"name":"First","tags":["foo"]}');
INSERT INTO jsonthings VALUES ('{"name":"Second","tags":["foo","bar"]}');
INSERT INTO jsonthings VALUES ('{"name":"Third","tags":["bar","baz"]}');
INSERT INTO jsonthings VALUES ('{"name":"Fourth","tags":["baz"]}');
CREATE INDEX ON jsonthings USING GIN(d);
Run Code Online (Sandbox Code Playgroud)
并且在运行SELECT. SELECT获取值为单个项目的行的简单方法工作正常:
SELECT d FROM jsonthings WHERE d @> '{"name":"First"}';
Run Code Online (Sandbox Code Playgroud)
但是当尝试运行匹配多个值的查询时,name我无法找到如何使用索引。我试过了:
SELECT d FROM jsonthings WHERE d->>'name' = ANY(ARRAY['First', 'Second']);
SELECT d FROM jsonthings WHERE d->'name' ?| ARRAY['First', 'Second'];
SELECT d FROM jsonthings WHERE d#>'{name}' ?| ARRAY['First','Second'];
Run Code Online (Sandbox Code Playgroud)
并且所有这些都显示了对表的顺序扫描(enable_seqscan=false如果可能,我正在使用强制使用索引)。有什么方法可以重写查询以便它使用索引?我知道我可以这样做: …
我有一个使用 JSON 类型的列。我想执行查询以选择 JSON 字符串中特定字段的所有不同记录:即给定这三个文档
{
id: 1,
s: "foo"
},
{
id:2,
s: "bar"
},
{
id:3,
s: "foo"
},
Run Code Online (Sandbox Code Playgroud)
查询必须检查“s”键是否有不同的值,并返回 ID 为 1 和 2 的文档。
SQL Server 2016,我正在尝试处理一些常规数据并返回一个 JSON 对象以供另一个系统处理。另一个系统无法识别数组包装器,因此我尝试使用 WITHOUT_ARRAY_WRAPPER 来摆脱它。在子查询中使用时会返回奇怪的结果...
SELECT @@SERVERNAME AS [Servername],
( SELECT [Name], [Recovery_Model_Desc]
FROM sys.databases
WHERE name in ('master', 'model', 'msdb')
FOR JSON PATH
) AS d
FOR JSON PATH, ROOT('ServerInformation')
Run Code Online (Sandbox Code Playgroud)
这会产生预期的数据,使用数组包装器......
{"ServerInformation":[{"Servername":"MyServer","d":[{"Name":"master","Recovery_Model_Desc":"SIMPLE"},{"Name":"model","Recovery_Model_Desc" :"FULL"},{"Name":"msdb","Recovery_Model_Desc":"SIMPLE"}]}]}
但是, WITHOUT_ARRAY_WRAPPER 产生...
SELECT @@SERVERNAME AS [Servername],
( SELECT [Name], [Recovery_Model_Desc]
FROM sys.databases
WHERE name in ('master', 'model', 'msdb')
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) AS d
FOR JSON PATH, ROOT('ServerInformation')
Run Code Online (Sandbox Code Playgroud)
{"ServerInformation":[{"Servername":"MyServer","d":"{\"Name\":\"master\",\"Recovery_Model_Desc\":\"SIMPLE\"},{\"Name \":\"model\",\"Recovery_Model_Desc\":\"FULL\"},{\"Name\":\"msdb\",\"Recovery_Model_Desc\":\"SIMPLE\"}"}] }
而我希望它产生
{"ServerInformation":{"Servername":"MyServer","d":{"Name":"master","Recovery_Model_Desc":"SIMPLE"},{"Name":"model","Recovery_Model_Desc":" FULL"},{"Name":"msdb","Recovery_Model_Desc":"SIMPLE"}}}
错误或预期结果?
编辑:调整预期结果
我有一张看起来像这样的桌子
id | json_column
---+------------
1 | {"text1":"a", "text2":"b", "text3":"c", ....}
2 | {"text1":"b", "text2":"c", ....}
Run Code Online (Sandbox Code Playgroud)
我希望它像这样
text1 | text2 | text3 | ....
a | b | c | ....
b | c | d | ....
Run Code Online (Sandbox Code Playgroud)
我发现得到这个结果的一个变体是使用 json_populate_record() 并创建一个新类型 x as (text1 text, text2 text, text3 text,....) 所以我可以执行
select (json_populate_record(null::x, json_column)).* from table
Run Code Online (Sandbox Code Playgroud)
有没有另一种方法可以在不创建上述类型的情况下做到这一点?所有新列都可以有类型文本,那么可能有快捷方式吗?
我的问题是我在 aaaa_bbbb_cccc_d 形式的一个 json 字段中有 50 个键,因此手动为此创建一种类型会花费很多时间
我正在使用 9.5.4
使用普通的更新语句来更新 json(b) 列是否有任何缺点,如下所示:
update "events" set "properties" = '{"type":"graph"}'
Run Code Online (Sandbox Code Playgroud)
而不是使用 PostgreSQL 提供的 jsonb_set 函数,它会变成这样的语句:
update "events" set jsonb_set("properties", {'type'}, 'graph')
Run Code Online (Sandbox Code Playgroud)
当使用例如。一个 ORM,并在刚刚更新了 JSON 字段的模型上调用 .save(),第一个方法将被调用,但是由于 PostgreSQL 文档中没有提到这种做事方式,我担心这个可能有一些缺点。
鉴于我对数据库性能方面的任何事情都不太熟悉,我想我会来这里问一个问题。
提前致谢!
例如,假设我有一个中等行数(约 100,000 行)的表,其中一jsonb列包含以下示例数据:
{"name":"Bob", "favoriteColor":"red", "someOtherObject": {"somethingElse": true}}
Run Code Online (Sandbox Code Playgroud)
是否更有效:
在 jsonb 列上使用 GIN 索引,然后使用 Postgres 的内置 JSON 查询函数来提取数据
创建多列来表示可以搜索的内容,即一列用于name,一列用于favoriteColor等;在这些列上构建 b 树索引,然后运行select document from table where name = 'Bob'
一些其他的解决方案?
请记住,解决方案需要有效地支持like查询,以便能够搜索以给定输入字符串开头的值。
看起来我的问题很不寻常,因为我根本没有找到答案。让我们想象一下,我有一个A带有列的表:language和uri。
语言 | uri ----------|----------------- 茹 | 一些uri zh | 另一个uri ...
我的问题是:如何返回 JSON 对象而不是多行。例如:
{
"ru": "some-uri",
"en": "some-another-uri",
...
}
我正在尝试在 Postgres 中创建一个函数,该函数可以遍历给定jsonb对象中的每个键/值对。
create or replace function myFunction
(input jsonb)
returns jsonb as $$
BEGIN
// foreach(key in input)
// do some math operation on its corresponding value
returns input;
END; $$
Run Code Online (Sandbox Code Playgroud)
参数输入应为 jsonb 对象,例如{"a":1, "b":2, "c":3}.
我想遍历对象中的每个键/值对。从我的评论中可以看出,我曾经使用更通用的编程语言(如 c、java 等)编写后端代码。所以我不擅长 SQL。我曾尝试在线搜索,但他们谈论如何遍历jsonb数组而不是对象。所以真的卡在这里了。
Frequently in Javascript you'll have something like
[ 7,2, [6,7], 2,10 ]
Run Code Online (Sandbox Code Playgroud)
How would you query that structure with OPENJSON I would like this,
0, 7
1, 2
2, 6,
2, 7,
3, 2
4, 10
Run Code Online (Sandbox Code Playgroud)
I'm having a hard time conditionally unwrapping that JSON array.
declare @ex nvarchar(max) = '[ 7,2, [6,7], 2,10 ]';
Run Code Online (Sandbox Code Playgroud)
SELECT *
FROM OPENJSON(@ex, '$') AS j1
Run Code Online (Sandbox Code Playgroud)
This gets you to,
key value type
0 7 2 …Run Code Online (Sandbox Code Playgroud)