Update object identified by composite key with rails - ruby-on-rails

I have actually a table with components. Each component have a specific version like it is describe above (there are other attributes like name, component_type_id, ...):
id | version_id
-----+------------
167 | 1
167 | 96
167 | 97
167 | 98
167 | 99
166 | 1
166 | 92
The attributes "id" and "version_id" are a composite primary key, and I want to edit a object by identifying this composite PK.
If I want to update the version 99 of the component #167 =>
With rails when I do :
Component.where(id: 167, version_id: 99).first.update({"component_type_id"=>"5", "name"=>"CCC"})
Rails do that :
SELECT "components".* FROM "components" WHERE "components"."id" = $1 AND "components"."version_id" = $2 ORDER BY "components"."id" ASC LIMIT 1 [["id", 167], ["version_id", 99]]
UPDATE "components" SET "name" = $1, "updated_at" = $2 WHERE "components"."id" = 167 [["name", "CCC"], ["updated_at", "2016-04-19 08:05:09.049345"]]
But I want something like that :
UPDATE "components" SET "name" = $1, "updated_at" = $2 WHERE "components"."id" = 167 AND version_id = 99 [["name", "CCC"], ["updated_at", "2016-04-19 08:05:09.049345"]]
Thanks to help me
Cheers

Since these is only one record with the given id and version, Try:
Component.where(id: 167, version_id: 99).update_all(component_type_id: 5, name: "CCC")
In this way, Rails will not instance a record, avoid your problem.

Related

How to concat or Listagg two values in a same column to join it with the values in other column

I have two tables :
TABLE_A
pos_id res_id bb_id bsk_name
1122 10000 1444 type_1
1122 10000 5678 type_2
1122 10001 1444 type_1
1122 10001 5678 type_2
1122 10002 1467 type_1
1122 10002 5678 type_2
1122 10003 1467 type_1
1122 10003 5678 type_2
table_b
pos_id row_id bb_id bsk_name
1122 1 1444 type_1
1122 1 5678 type_2
1122 2 1467 type_1
1122 2 5678 type_2
I wanted to join the table_a and table_b to get the row_id for each res_id.
the res_id 10000 and 10001 has to have the row_id 1 and res_id 10002 and 10003 has to have the row_id 2. but since there is no unique column to join these two tables i get duplicated values for the bb_id 5678 since they are the same in both row_id's.
So Is there a way like to listagg the bb_id's with the erg_id in table_a and row_id in table_b to join these two tables ?
You can use CAST(COLLECT(...) AS ...) to aggregate the rows into a user-defined collection and then compare the collections.
First, create a nested-table-type collection:
CREATE TYPE int_list AS TABLE OF INT;
Then you can use:
SELECT a.pos_id,
a.res_id,
a.bb_id,
a.bsk_name,
b.row_id,
b.bsk_name
FROM (
SELECT a.*,
CAST(
COLLECT(bb_id) OVER (PARTITION BY pos_id, res_id)
AS int_list
) AS all_bb_ids
FROM table_a a
) a
INNER JOIN (
SELECT b.*,
CAST(
COLLECT(bb_id) OVER (PARTITION BY pos_id, row_id)
AS int_list
) AS all_bb_ids
FROM table_b b
) b
ON ( a.pos_id = b.pos_id
AND a.all_bb_ids = b.all_bb_ids
AND a.bb_id = b.bb_id)
Which, for your sample data:
CREATE TABLE TABLE_A ( pos_id, res_id, bb_id, bsk_name ) AS
SELECT 1122, 10000, 1444, 'type_1' FROM DUAL UNION ALL
SELECT 1122, 10000, 5678, 'type_2' FROM DUAL UNION ALL
SELECT 1122, 10001, 1444, 'type_1' FROM DUAL UNION ALL
SELECT 1122, 10001, 5678, 'type_2' FROM DUAL UNION ALL
SELECT 1122, 10002, 1467, 'type_1' FROM DUAL UNION ALL
SELECT 1122, 10002, 5678, 'type_2' FROM DUAL UNION ALL
SELECT 1122, 10003, 1467, 'type_1' FROM DUAL UNION ALL
SELECT 1122, 10003, 5678, 'type_2' FROM DUAL;
CREATE TABLE table_b (pos_id, row_id, bb_id, bsk_name) AS
SELECT 1122, 1, 1444, 'type_1' FROM DUAL UNION ALL
SELECT 1122, 1, 5678, 'type_2' FROM DUAL UNION ALL
SELECT 1122, 2, 1467, 'type_1' FROM DUAL UNION ALL
SELECT 1122, 2, 5678, 'type_2' FROM DUAL;
Outputs:
POS_ID
RES_ID
BB_ID
BSK_NAME
ROW_ID
BSK_NAME
1122
10000
1444
type_1
1
type_1
1122
10000
5678
type_2
1
type_2
1122
10001
1444
type_1
1
type_1
1122
10001
5678
type_2
1
type_2
1122
10002
1467
type_1
2
type_1
1122
10002
5678
type_2
2
type_2
1122
10003
1467
type_1
2
type_1
1122
10003
5678
type_2
2
type_2
db<>fiddle here
Update
You could also use LISTAGG to aggregate the data; however, if the aggregated string will exceed 4000 bytes then the aggregation will fail (using CAST(COLLECT(...) ...) does not have this limitation but does require you create a collection data type):
SELECT a.pos_id,
a.res_id,
a.bb_id,
a.bsk_name,
b.row_id,
b.bsk_name
FROM (
SELECT a.*,
LISTAGG(bb_id, ',') WITHIN GROUP (ORDER BY bb_id)
OVER (PARTITION BY pos_id, res_id) AS all_bb_ids
FROM table_a a
) a
INNER JOIN (
SELECT b.*,
LISTAGG(bb_id, ',') WITHIN GROUP (ORDER BY bb_id)
OVER (PARTITION BY pos_id, row_id) AS all_bb_ids
FROM table_b b
) b
ON ( a.pos_id = b.pos_id
AND a.all_bb_ids = b.all_bb_ids
AND a.bb_id = b.bb_id)
db<>fiddle here

Inner join return duplicated record

My table:
Report_Period
Entity
Tag
Users Count
Report_Period_M-1
Report_Period_Q-1
...
2017-06-30
entity 1
X
471
2017-05-31
2017-03-31
...
2020-12-31
entity 2
A
135
2020-11-30
2020-09-30
...
2020-11-30
entity 3
X
402
2020-10-31
2020-08-31
...
What I want:
Report_Period
Entity
Tag
Users Count
Users_Count_M-1
Users_Count_Q-1
...
2017-06-30
entity 1
X
471
450
438
...
2020-12-31
entity 2
A
135
122
118
...
2020-11-30
entity 3
X
402
380
380
...
I have have tried this code but it duplicate records! How can I avoid it?
SELECT M."Entity",M."Tag",M."Report_Period",M."Users Count",
M."Report_Period_M-1",M1."Users Count" AS "Users Count M1",
FROM "DB"."SCHEMA"."PERIOD" M, "DB"."SCHEMA"."PERIOD" M1
WHERE M."Report_Period_M-1"= M1."Report_Period"
Your join clause should include the entity column and tag (I suspect)
SELECT M."Entity",
M."Tag",
M."Report_Period",
M."Users Count",
M."Report_Period_M-1",
M1."Users Count" AS "Users Count M1",
FROM "DB"."SCHEMA"."PERIOD" M,
"DB"."SCHEMA"."PERIOD" M1
WHERE M."Report_Period_M-1"= M1."Report_Period"
AND M."Entity" = M1."Entity"
AND M."Tag" = M1."Tag"

Neo4j visualization with py2neo: TypeError: 'LabelSetView' object is not callable

I am trying to follow the example in
https://nicolewhite.github.io/neo4j-jupyter/hello-world.html
from scripts.vis import draw
import neo4jupyter
options = {"Person": "name", "Drink": "name", "Manufacturer": "name"}
draw(graph, options)
For this part of the code, I encounter this error:
ypeError Traceback (most recent call last)
<ipython-input-7-6a87e5426fa3> in <module>
3
4 options = {"Person": "name", "Drink": "name", "Manufacturer": "name"}
----> 5 draw(graph, options)
~\PycharmProjects\Knowledge_Graph\scripts\vis.py in draw(graph, options, physics, limit)
104 target_id = row[4]
105
--> 106 source_info = get_vis_info(source_node, source_id)
107
108 if source_info not in nodes:
~\PycharmProjects\Knowledge_Graph\scripts\vis.py in get_vis_info(node, id)
91
92 def get_vis_info(node, id):
---> 93 node_label = list(node.labels())[0]
94 prop_key = options.get(node_label)
95 vis_label = node.properties.get(prop_key, "")
TypeError: 'LabelSetView' object is not callable
I read online that there might be some issues with scripts.vis but I am not too sure how to resolve it
Please checkout the latest version from the below link and it fixes the problem
https://github.com/merqurio/neo4jupyter/issues/5

aggration and self join

hi I am working on this query, wondering whether there is a good way to achieve. TableA as
zone_no price produceDate
54 12.33 20161201
58 7.88 20161224
64 28.27 20160812
67 20.45 20160405
87 14.08 20161102
92 1.69 20160101
101 12.57 20140501
141 22.21 20150601
157 14.28 20160417
select max(price) from tableA where zone_no between 54 and 145
select max(price) from tableA where Zone_no between 92 and 141
outcome:
price(Zone 54-145) price(zone 92-141)
28.27 22.57
how to achieve this without CTE? thanks
alternative solution
select sum(een), sum(twee) from (
select max(price) as een, 0 as twee from tableA where zone_no between 54 and 145
union
select 0, max(price) from tableA where Zone_no between 92 and 141
)

Entity framework joins

I'm using the entity framework 4.0 and I'm having some issues with the syntax of my query. I'm trying to join 2 tables and pass a parameter to find the value at the same time.I would like find all of the products in table 2 by finding the correlating value in table 1.
Can someone help me out with syntax please?
Thanks in advance.
sample data
table 1
ID productID categoryID
361 571 16
362 572 17
363 573 16
364 574 19
365 575 26
table 2
productID productCode
571 sku
572 sku
573 sku
574 sku
575 sku
var q = from i in context.table1
from it in context.table2
join <not sure>
where i.categoryID == it.categoryID and < parameter >
select e).Skip(value).Take(value));
foreach (var g in q)
{
Response.Write(g.productID);
}
var q = from i in context.table1
join it in context.table2 on i.productID equals it.productID
where i.categoryID == it.categoryID and it.productCode = xyz
select i).Skip(value).Take(value));

Resources