Merge records from two tables - sql

I have two model Part and DamagedPart.
All of them have iid field.
I want to get combined ActiveRecord object with data from these two tables.
Say, parts table has 10 records:
id: 1, iid: 100, d: 0
id: 2, iid: 150, d: 0
id: 3, iid: 200, d: 0
id: 4, iid: 240, d: 0
id: 5, iid: 433, d: 0
...
And damaged_parts table has only two records (for example):
id: 10, iid: 200, d: 4
id: 20, iid: 240, d: 7
Finally I need to get:
id: 1, iid: 100, d: 0
id: 2, iid: 150, d: 0
id: 10, iid: 200, d: 4 # <--- replaced from 'damaged_parts' table
id: 20, iid: 240, d: 7 # <--- replaced from 'damaged_parts' table
id: 5, iid: 433, d: 0
...
Can I get this done by one AR query?
Rails: 4.2.7.1
RDBMS: MariaDB 10.0.27

You need LEFT JOIN and COALESCE
SELECT p.id,
p.iid,
COALESCE(dp.d, p.d) AS d
FROM parts p
LEFT JOIN damaged_parts dp
ON p.id = dp.id
AND p.iid = dp.iid

You can try this.
Part.joins("LEFT OUTER JOIN damaged_parts ON parts.iid = damaged_parts.iid").select("coalesce(damaged_parts.id, parts.id) as id, parts.iid, coalesce(damaged_parts.d, parts.d) as d");

Select FROM parts WHERE iid LIKE'[1-]%';
UNION Select FROM damaged_parts WHERE iid LIKE'[1-]%';

Related

Can the right column be fixed in the bootstrap-vue table?

I want right fixed columns in the bootstrap-vue table
but, the Sticky function in the document is only fixed to the left.
Is there a way to fix the right side or last columns?
I want both the left and right columns being fixed in place.
documnet : https://bootstrap-vue.org/docs/components/table#sticky-columns
<template>
<div>
<div class="mb-2">
<b-form-checkbox v-model="stickyHeader" inline>Sticky header</b-form-checkbox>
<b-form-checkbox v-model="noCollapse" inline>No border collapse</b-form-checkbox>
</div>
<b-table
:sticky-header="stickyHeader"
:no-border-collapse="noCollapse"
responsive
:items="items"
:fields="fields"
>
<!-- We are using utility class `text-nowrap` to help illustrate horizontal scrolling -->
<template #head(id)="scope">
<div class="text-nowrap">Row ID</div>
</template>
<template #head()="scope">
<div class="text-nowrap">
Heading {{ scope.label }}
</div>
</template>
</b-table>
</div>
</template>
<script>
export default {
data() {
return {
stickyHeader: true,
noCollapse: false,
fields: [
{ key: 'id', stickyColumn: true, isRowHeader: true, variant: 'primary' },
'a',
'b',
{ key: 'c', stickyColumn: true, variant: 'info' },
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l'
],
items: [
{ id: 1, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
{ id: 2, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
{ id: 3, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
{ id: 4, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
{ id: 5, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
{ id: 6, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
{ id: 7, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
{ id: 8, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
{ id: 9, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
{ id: 10, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 }
]
}
}
}
</script>
It's possible by overriding bootstrap's CSS with some of our own. First make sure the last column has the stickyColumn: true option plus whatever other options you want to give it:
...
'i',
'j',
'k',
{ key: "l", stickyColumn: true, isRowHeader: true, variant: "primary" },
This will ensure it has a classname we can easily select on. Apply styling that gives the last sticky column in the table an attribute of right: 0:
<style>
.b-table-sticky-column:last-child {
right: 0;
}
</style>
codesandbox example

Converting from Spell Format to STS when each individual has multiple, separate spells

I am trying to convert data of this form to STS format in order to perform sequence analysis:
|Person ID |Spell |Start Month |End Month |Status (Economic Activity) |
| -------- |----- |------------|----------|---------------------------|
|1|1|300|320|4|
|1|2|320|360|4|
|2|1|330|360|4|
|3|1|270|360|7|
|4|1|280|312|4|
|4|2|312|325|4|
|4|3|325|360|6|
Does anyone know how I can deal with the issue of multiple spells per person and somehow combine each spell for a given individual?
You should have a look at TraMiner's excellent documentation. Particularly, the user guide is very helpful. There you would find a section on the seqformat function, which is exactly what you are looking for
library(TraMineR)
## Create spell data
data <-
as.data.frame(
matrix(
c(1, 1, 300, 320, 4,
1, 2, 320, 360, 4,
2, 1, 330, 360, 4,
3, 1, 270, 360, 7,
4, 1, 280, 312, 4,
4, 2, 312, 325, 4,
4, 3, 325, 360, 6),
ncol = 5, byrow = T)
)
names(data) <- c("id", "spell", "start", "end", "status")
## Converting from SPELL to STS format with TraMineR::seqformat
data.sts <-
seqformat(data, from = "SPELL", to = "STS",
id = "id", begin = "start", end = "end", status = "status",
process = FALSE)

How do I insert and update array columns in Node-Postgres?

I have the following table in Postgres:
_id: integer, user_id: integer, items: Array
I wish to insert the following into the table:
1, 1, [{productId: 1, size: 'large', quantity: 5}]
Next I wish to update the row with the following:
1, 1, [{productId: 1, size: 'small', quantity: 3}]
How do I do this in node-postgres?
Pseudocode:
update cart
set items.quantity = 3
where cart._id = 1
and cart.items.product_id = 1
and cart.items.size='large'

Replace values by indices of corresponding to another array

I am a newbie in numpy. I have an array A of size [x,] of values and an array B of size [y,] (y > x). I want as result an array C of size [x,] filled with indices of B.
Here is an example of inputs and outputs:
>>> A = [10, 20, 30, 10, 40, 50, 10, 50, 20]
>>> B = [10, 20, 30, 40, 50]
>>> C = #Some operations
>>> C
[0, 1, 2, 0, 3, 4, 0, 4, 1]
I didn't find the way how to do this. Please advice me. Thank you.
I think you are looking for searchsorted, assuming that B is sorted increasingly:
C = np.searchsorted(B,A)
Output:
array([0, 1, 2, 0, 3, 4, 0, 4, 1])
Update for general situation where B is not sorted. We can do an argsort:
# let's swap 40 and 50 in B
# expect the output to have 3 and 4 swapped
B = [10, 20, 30, 50, 40]
BB = np.sort(B)
C = np.argsort(B)[np.searchsorted(BB,A)]
Output:
array([0, 1, 2, 0, 4, 3, 0, 3, 1], dtype=int64)
You can double check:
(np.array(B)[C] == A).all()
# True
For general python lists
A = [10, 20, 30, 10, 40, 50, 10, 50, 20]
B = [10, 20, 30, 40, 50]
C = [A.index(e) for e in A if e in B]
print(C)
You can try this code
A = np.array([10, 20, 30, 10, 40, 50, 10, 50, 20])
B = np.array([10, 20, 30, 40, 50])
np.argmax(B==A[:,None],axis=1)

Line Chart with Int as x axis, not Date

I would like to display a chart which shows integers on the x axis instead of dates.
Here is a fiddle of the example:
http://jsfiddle.net/cs3vigny/srmqcfjh/
new Morris.Line({
element: 'film-compare-chart',
data: [
{ week: 0, a: 2, b: 4, c: 5, d: 3, e: 3 },
{ week: 1, a: 2, b: 3, c: 6, d: 3, e: 3 },
{ week: 2, a: 3, b: 5, c: 4, d: 2, e: 2 },
{ week: 3, a: 3, b: 6, c: 6, d: 3, e: 4 },
{ week: 4, a: 4, b: 4, c: 5, d: 4, e: 2 },
{ week: 5, a: 4, b: 6, c: 6, d: 3, e: 2 },
{ week: 6, a: 4, b: 7, c: 8, d: 5, e: 2 },
{ week: 7, a: 3, b: 5, c: 6, d: 5, e: 4 },
{ week: 8, a: 4, b: 8, c: 6, d: 4, e: 3 },
{ week: 9, a: 6, b: 10, c: 8, d: 7, e: 5 },
{ week: 10, a: 5, b: 12, c: 13, d: 7, e: 4 },
{ week: 11, a: 6, b: 10, c: 10, d: 7, e: 4 },
{ week: 12, a: 9, b: 10, c: 10, d: 10, e: 6 },
{ week: 13, a: 11, b: 15, c: 16, d: 12, e: 9 },
{ week: 14, a: 14, b: 15, c: 14, d: 13, e: 10 },
{ week: 15, a: 14, b: 20, c: 17, d: 15, e: 11 },
{ week: 16, a: 18, b: 26, c: 22, d: 16, e: 15 },
{ week: 17, a: 19, b: 22, c: 22, d: 18, e: 13 },
{ week: 18, a: 19, b: 21, c: 25, d: 20, e: 16 },
{ week: 19, a: 26, b: 26, c: 33, d: 24, e: 21 },
{ week: 20, a: 26, b: 26, c: 31, d: 24, e: 21 },
{ week: 21, a: 24, b: 28, c: 41, d: 26, e: 22 },
{ week: 22, a: 33, b: 32, c: 40, d: 29, e: 28 },
{ week: 23, a: 34, b: 37, c: 51, d: 34, e: 32 }
],
xkey: 'week',
ykeys: ['a','b','c','d','e'],
labels: ['Cinderella (2015)', 'Maleficent', 'Oz: The Great and Powerful', 'Divergent', 'Big Hero 6']
});
Does Morris.js only display dates on the x-axis no matter what or can that be changed?
Try adding option parameter parseTime:false.
In Morrischart,if 'parseTime' set to false then it skip time/date parsing for X values, Otherwise it treating them as an equally-spaced series;the default value is parseTime:true..thats why you get confused..So could you please insert the below line of code
parseTime:false
sample code like as follows,
new Morris.Area({
------
parseTime:false,
------
});
Hope its works fine :-)