I have 3 different tables:
Store:
- id
- name
- address
Product:
- id
- name
- category
- price
Order:
- id
- product_id
- store_id
- amount
- discount
I need to retrieve some statistic data from these 3 tables.
I'm trying to query JSON object but had no success in that.
Target json object:
{
"results": {
"store": "Store #123",
"products": [
"product": {
"id": 123,
"name": "Some name"
}
"orders_count": 123,
"orders_summ": 123456,
]
}
}
As you can see I use aggregation functions to calculate orders_count and orders_summ
Related
In relation store has many products.
I created the struct like this:
type Store1 struct {
StoreSeq uint `json:"storeSeq" gorm:"primaryKey; column:store_seq"`
NickName string `json:"nickName" gorm:"column:nick_name"`
RegDate *domain.CTime `json:"regDate" gorm:"column:reg_date"`
Product1 []Product1 `json:"products" gorm:"foreignKey:ProductSeq"`
}
func (*Store1) TableName() string {
return "store"
}
type Product1 struct {
ProductSeq uint `json:"productSeq"`
ProductTitle string `json:"productTitle"`
RegDate *domain.CTime `json:"regDate"`
StoreSeq *uint `json:"store_seq" `
}
func (*Product1) TableName() string {
return "product"
}
and I queried it like this:
pro := new(entity.Product1)
store := new(entity.Store1)
orm.GetData().
Model(pro).
Preload("Product1").
Joins("left join store on store.store_seq = product.store_seq").
Where("store.store_seq = ?", 1).
Find(&store)
In my database table has data like this
STORE
1 testStore 2022-03-01 23:19:18
PRODUCT
1 1 test 2022-03-01 23:19:18
2 1 testaaa 2022-03-01 23:19:18
I expect
"storeSeq": 1,
"nickName": "",
"regDate": "2022-03-01 23:19:18",
"products": [
{
"productSeq": 1,
"productTitle": "test",
"regDate": "2022-03-01 23:19:18",
"store_seq": 1
},
{
"productSeq": 2,
"productTitle": "testaaa",
"regDate": "2022-03-01 23:19:18",
"store_seq": 1
}
]
but it only returns one result:
"storeSeq": 1,
"nickName": "",
"regDate": "2022-03-01 23:19:18",
"products": [
{
"productSeq": 1,
"productTitle": "test",
"regDate": "2022-03-01 23:19:18",
"store_seq": 1
}
]
I checked the SQL query then I found that it executes two SQL queries
[1.725ms] [rows:2] SELECT `product`.`product_seq`,`product`.`product_title`,`product`.`reg_date`,`product`.`store_seq` FROM `product` WHERE `product`.`product_seq` = 1
AND
[6.370ms] [rows:1] SELECT `product`.`product_seq`,`product`.`product_title`,`product`.`reg_date`,`product`.`store_seq` FROM `product` left join store on store.store_seq = product.store_seq WHERE store.store_seq = 1
I don't know why it executes the first SQL query; I want it to execute the second query only.
I have no idea and this is my firstime to use Golang with gorm with serverless framework
I found out that I make wrong releation between product and store
store has many produts so I have to relation product1 []Product1 foriegnKey
with storeSeq but i set foriegnkey as product_seq
and i also find out that execute two queries it because of preload option.
Lets say I have this Json and I would like to retrieve all the age values where the name equals Chris in the Array key.
{
"Array": [
{
"age": "65",
"name": "Chris"
},
{
"age": "20",
"name": "Mark"
},
{
"age": "23",
"name": "Chris"
}
]
}
That Json is present in the Json column inside my database.
by that I would like to retrieve one age column the has the age 65 and 23 because they both named Chris.
Use json_each() table-valued function to extract all the names and ages from the json array of each row of the table and json_extract() function to filter the rows for 'Chris' and get his age:
SELECT json_extract(j.value, '$.name') name,
json_extract(j.value, '$.age') age
FROM tablename t JOIN json_each(t.col, "$.Array") j
WHERE json_extract(j.value, '$.name') = 'Chris';
Change col to the name of the json column.
See the demo.
I'm trying to compare 2 arrays in a sql query. Everything seems to work fine while getting data from dynamodb and MQTT broker server.
But if I try to compare both arrays, doesn't return anything or its undefined.
My sql query:
SELECT ts, objects, (SELECT id FROM get_dynamodb('table', 'key_name', 'key_value', 'rolearn').ids) AS db, (SELECT id from objects) as obj_ids
FROM 'subscribed/topic'
WHERE objects <> []
Result:
{
"ts": 1615807935588,
"objects": [
{
"id": 1,
"planet": "jupiter"
},
{
"id": 2,
"planet": "mars"
},
],
"db": [
{
"id": 2
},
{
"id": 3
}
],
"obj_ids": [
{
"id": 1
},
{
"id": 2
}
]
}
So far it's ok, now all I want to do is compare if "obj_ids" and "db" arrays are different (obj_ids <> db), and by the aws documentation https://docs.aws.amazon.com/iot/latest/developerguide/iot-sql-operators.html#iot-sql-operators-not-eq I can compare both arrays.
So if I do:
SELECT ts, objects, (SELECT id FROM get_dynamodb('table', 'key_name', 'key_value', 'rolearn').ids) AS db, (SELECT id from objects) as obj_ids
FROM 'subscribed/topic'
WHERE objects <> []
AND obj_ids <> db
The code doesn't return anything. I've already tested comparing 2 objects arrays hardcoded into the query and it works just has I intended.
SELECT ([{"id": 1},{"id": 2}] <> [{"id": 1}]) as result
FROM 'subscribed/topic'
Result:
{
"result": true
}
Any response will be appretiated.
Thanks!
Credits from Ben T
As AWS Docs WHERE clause says:
"you cannot reference any aliases created with the AS keyword in the SELECT. The WHERE clause is evaluated first, to determine if SELECT is evaluated."
So all I needed to do is move the (SELECT id FROM get_dynamodb('table', 'key_name', 'key_value', 'rolearn').ids) and (SELECT id from objects) to the WHERE clause.
Final query:
SELECT ts, objects
FROM 'subscribed/topic'
WHERE objects <> []
AND (SELECT id from objects) <> (SELECT id FROM get_dynamodb('table', 'key_name', 'key_value', 'rolearn').ids)
I has table "Product" with two columns:
Id - Bigint primary key
data - Jsonb
Here example of json:
{
"availability": [
{
"qty": 10,
"price": 42511,
"store": {
"name": "my_best_store",
"hours": null,
"title": {
"en": null
},
"coords": null,
"address": null,
I insert json to column "data".
Here sql get find "my_best_store"
select *
from product
where to_tsvector(product.data) ## to_tsquery('my_best_store')
Nice. It's work fine.
But I need to find "my_best_store" only in section "availability".
I try this but result is empty:
select *
from product
where to_tsvector(product.data) ## to_tsquery('availability & my_best_store')
Assuming you want to search in the name attribute, you can do the following:
select p.*
from product p
where exists (select *
from jsonb_array_elements(p.data -> 'availability') as t(item)
where to_tsvector(t.item -> 'store' ->> 'name') ## to_tsquery('my_best_store'))
With Postgres 12, you can simplify that to:
select p.*
from product p
where to_tsvector(jsonb_path_query_array(data, '$.availability[*].store.name')) ## to_tsquery('my_best_store')
I have a table (log_table) and in this table there is a nested array json field (activities). With using this activities field, I want to normalize my row.
log_table:
- id:long
- activities:json
- date:timestamp
example activities field:
[
{
"actionType":"NOTIFICATION",
"items":null
},
{
"actionType":"MUTATION",
"items":[
{
"id":387015007,
"name":"epic",
"value":{
"currency":"USD",
"amount":1.76
}
},
{
"id":386521039,
"name":"test",
"value":{
"currency":"USD",
"amount":1.76
}
}
]
}
]
As query, I've tried:
select
*
from
log_table l,
json_array_elements(l.activities) elems,
json_array_elements(elems->'items') obj;
With this query, I got error like below:
ERROR: cannot call json_array_elements on a scalar
Is there any suggestion?
The lack of items should be marked as [null], not null. You can use the case expression to correct this, e.g.:
select elems->>'actionType' as action_type, obj
from log_table
cross join jsonb_array_elements(l.activities::jsonb) elems
cross join jsonb_array_elements(case elems->'items' when 'null' then '[null]' else elems->'items' end) obj
action_type | obj
--------------+---------------------------------------------------------------------------------
NOTIFICATION | null
MUTATION | {"id": 387015007, "name": "epic", "value": {"amount": 1.76, "currency": "USD"}}
MUTATION | {"id": 386521039, "name": "test", "value": {"amount": 1.76, "currency": "USD"}}
(3 rows)