I have the following data:
<node:1><urn:connectTo><node:2>
<node:1><urn:connectTo><node:3>
<node:1><urn:connectTo><node:4>
<node:2><urn:connectTo><node:10>
<node:2><urn:connectTo><node:11>
<node:2><urn:connectTo><node:12>
<node:3><urn:connectTo><node:21>
<node:3><urn:connectTo><node:13>
<node:3><urn:connectTo><node:41>
<node:3><urn:connectTo><node:100>
<node:4><urn:connectTo><node:119>
<node:4><urn:connectTo><node:120>
As you can see, every node has multiple connections. I want to select one connection randomly for each node. How can I do this? I've tried the following queries, but none solve the problem:
select ?currentNode ?nextNode where {
?currentNode ?p ?nextNode
BIND(RAND() AS ?orderKey)
}
ORDER BY ?orderKey
LIMIT 1
select ?currentNode SAMPLE(?nextNode) as ?nextNode1
where {
?currentNode ?p ?nextNode
}
GROUP BY ?currentNode
Note: the result gives the first connection of each node but not randomly
select ?currentNode ?nextNode (COUNT(?nextNode) AS ?noOfChoices)
where {
?currentNode ?p ?nextNode
BIND(RAND() AS ?orderKey)
}
GROUP BY ?currentNode
ORDER BY ?orderKey
OFFSET (RAND()*?noOfChoices)
LIMIT 1
The sample aggregate returns an individual from within a group:
Sample is a set function which returns an arbitrary value from the
multiset passed to it. … For example, given Sample({"a", "b",
"c"}), "a", "b", and "c" are all valid return values. Note that
Sample() is not required to be deterministic for a given input, the
only restriction is that the output value must be present in the input
multiset.
This would be a query like:
prefix node: <node:>
prefix urn: <urn:>
select ?source (sample(?_target) as ?target) where {
?source urn:connectTo ?_target
}
group by ?source
---------------------
| source | target |
=====================
| node:1 | node:2 |
| node:2 | node:10 |
| node:3 | node:13 |
| node:4 | node:119 |
---------------------
Of course, as you note, the implementation just has to return an arbitrary individual. This could easily be the same one each time. You could do some ordering in a subquery and hope to randomize the order of the targets in order to get different results from sample, but there's no requirement that the order of results from a subquery is preserved either. That would look like this:
prefix node: <node:>
prefix urn: <urn:>
select ?source (sample(?_target) as ?target) where {
{ select ?source ?_target {
?source urn:connectTo ?_target
}
order by rand() }
}
group by ?source
This seems to work with Apache Jena. Here are results from repeated calls:
---------------------
| source | target |
=====================
| node:1 | node:2 |
| node:2 | node:11 |
| node:3 | node:100 |
| node:4 | node:120 |
---------------------
---------------------
| source | target |
=====================
| node:1 | node:3 |
| node:2 | node:11 |
| node:3 | node:13 |
| node:4 | node:120 |
---------------------
---------------------
| source | target |
=====================
| node:1 | node:3 |
| node:2 | node:10 |
| node:3 | node:21 |
| node:4 | node:119 |
---------------------
---------------------
| source | target |
=====================
| node:1 | node:3 |
| node:2 | node:10 |
| node:3 | node:100 |
| node:4 | node:119 |
---------------------
Related
I have the following setup:
stages:
| id | name | order |
commands:
| id | name | body |
------------------------------=
| 1 | test | phpunit |
| 2 | style | echo "style" |
| 3 | deploy | deploy |
command_stage:
| command_id | stage_id | order |
---------------------------------
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 1 | 2 |
Basically, I would like to create a method on the stage model which allows me to get all of the commands back based off of the order, but commands have a specific order and so do the stages.
So each command is stored under a stage so we know which part to run but each command also has an order in that stage. Now I know I can do something like the following:
$inOrder = collect();
Stage::get()->each(function ($stage) {
$commands = $stage->commands()->orderByPivot('order')->get();
$inOrder->push($commands);
});
return $inOrder;
But I was wondering if there is a nicer way to do this? Or even a way to do this solely on one database hit?
Pre-load and sort the relationship:
$stages = Stage::with(['commands' => function ($subQuery) {
$subQuery->orderBy('command_stage', 'order');
}])->get();
foreach($stages as $stage) {
$inOrder->push($stage->commands);
}
This method of Eager-Loading will reduce the N+1 query issue of doing $stage->commands() inside the foreach() loop.
I have a list of users, and I'm trying to get the result of each unique domain in users' email addresses and their totals.
So, let's say I have these 5 users:
+--------------------------------------+--------------------------------+-------------+------------+-------------+
| id | email | firstname | lastname | something |
+--------------------------------------+--------------------------------+-------------+------------+-------------+
| 00c0f0db-87d0-45b2-8ed2-aa94d1e3e659 | shane.conte#jourrapide.com | Shane | Conte | iew9anap0L |
+--------------------------------------+--------------------------------+-------------+------------+-------------+
| 0114360a-3ef8-49d6-8c51-02392bc51e10 | michelle.guitierrez#dayrep.com | Michelle | Guitierrez | eeNgiev3foh |
+--------------------------------------+--------------------------------+-------------+------------+-------------+
| 00e8e2f2-2130-4f65-8914-b93d5b029d75 | terri.hebert#rhyta.com | Terri | Hebert | vahMoKiuCh0 |
+--------------------------------------+--------------------------------+-------------+------------+-------------+
| 00e1578b-cf6d-46b8-92e3-2388a80105f7 | richard.copeland#dayrep.com | Richard | Copeland | Iem4mohng |
+--------------------------------------+--------------------------------+-------------+------------+-------------+
| 00f1be34-d60e-4b2f-b3ae-610c67151f2d | elsie.fuhrman#rhyta.com | Elsie | Fuhrman | aPie6piD6ae |
+--------------------------------------+--------------------------------+-------------+------------+-------------+
After running the query, I'd like to see this result:
+-------+----------------+
| count | domain |
+-------+----------------+
| 1 | jourrapide.com |
+-------+----------------+
| 2 | dayrep.com |
+-------+----------------+
| 2 | rhyta.com |
+-------+----------------+
I'm currently running this query below to get the unique domains but if I try to run count() in it, it dramatically fails after 300 seconds, which I expect to happen since I have A LOT more than 5 users :)
r.db('helloworld').table('users').pluck('email').map(function(user) {
return user('email').split('#').nth(1).downcase()
}).distinct().map(function(domain) {
return {
count: '???', // <--- this is where I need help
domain: domain
}
})
And as you can imagine, it perfectly returns this result:
+-------+----------------+
| count | domain |
+-------+----------------+
| ??? | jourrapide.com |
+-------+----------------+
| ??? | dayrep.com |
+-------+----------------+
| ??? | rhyta.com |
+-------+----------------+
I hope this makes sense. If you think I'm on a wrong path, feel free to suggest any other way.
Thanks in advance!
You can't distinct() to count(). Instead you want to group():
r.db('helloworld').table('users').pluck('email').map(function(user) {
// wrap the result in an object for grouping purposes
return { domain: user('email').split('#').nth(1).downcase() };
})
// this groups all domains together in a [{ group, reduction }] list of objects
.group('domain')
// after group(), calls are scoped to each reduction: count each one
.count()
// let's ungroup to scope the following calls to the whole sequence
.ungroup()
// let's be compliant with the format you expect
.map(function(doc) {
return {
domain: doc('group'),
count: doc('reduction')
};
});
Given this ridiculously simple data set:
+--------+-----+
| Bucket | Foo |
+--------+-----+
| 1 | A |
| 1 | B |
| 1 | C |
| 1 | D |
+--------+-----+
I want to see the value of Foo in the previous row:
select
foo,
max(foo) over (partition by bucket order by foo rows between 1 preceding and 1 preceding) as prev_foo
from
...
Which gives me:
+--------+-----+----------+
| Bucket | Foo | Prev_Foo |
+--------+-----+----------+
| 1 | A | A |
| 1 | B | A |
| 1 | C | B |
| 1 | D | C |
+--------+-----+----------+
Why do I get 'A' back for the first row? I would expect it to be be null. It's throwing off calculations where I'm looking for that null. I can work around it by throwing a row_number() in there, but I'd prefer to handle it with fewer calcs.
use the LAG function to get previous row:
LAG(foo) OVER(partition by bucket order by foo) as Prev_Foo
I've a question regarding how Laravel handles pivot tables:
Summarizing: 2 models, Project and Stage.
Project
+----+----------+
| id | name |
+----+----------+
| 1 | Project1 |
| 2 | Project2 |
+----+----------+
Stage
+----+--------+
| id | name |
+----+--------+
| 1 | Stage1 |
| 2 | Stage2 |
| 3 | Stage3 |
+----+--------+
And a pivot table
+----+------------+----------+------------+-----------+
| id | project_id | stage_id | date | info |
+----+------------+----------+------------+-----------+
| 1 | 1 | 1 | 2014-12-20 | Moreinfo1 |
| 2 | 1 | 2 | 2014-12-21 | Moreinfo2 |
| 3 | 2 | 1 | 2014-12-22 | Moreinfo3 |
| 4 | 1 | 3 | 2014-12-23 | Moreinfo4 |
+----+------------+----------+------------+-----------+
I'm showing the info:
+----------+------------+------------+-----------+
| project | last_stage | date | info |
+----------+------------+------------+-----------+
| Project1 | 3 | 2014-12-23 | Moreinfo4 |
| Project2 | 1 | 2014-12-22 | Moreinfo3 |
+----------+------------+------------+-----------+
And everything works fine; however, if I add a new Project (as there's no info on the pivot table), I get the annoying:
Whoops, looks like something went wrong.
Is there any way to indicate that, in case of null, the row should be left empty (without an error)? I'd like to get:
+----------+------------+------------+-----------+
| project | last_stage | date | info |
+----------+------------+------------+-----------+
| Project1 | 3 | 2014-12-23 | Moreinfo4 |
| Project2 | 1 | 2014-12-22 | Moreinfo3 |
| Project3 | | | |
+----------+------------+------------+-----------+
The problem is the call in your view:
{{ $project->stages_accomp()->orderBy('date', 'desc')->first()->pivot->date }}
When you have a project that has no stage assigned ->first() will return null.
And PHP doesn't like it if you want to access a property of a non-object (in this case null)
You need to add a little check like this:
#if($stage = $project->stages_accomp()->orderBy('date', 'desc')->first())
{{ $stage->pivot->date }}
#endif
It will make sure the first() returns a truthy value (not null) and will also assign the value to the variable $stage.
I've got the following problem:
There is a Postgres database which I need to get data from, via a Nagios Linux distribution.
My intention is to make a resulting SELECT be saved to a .txt, that would be sent via email to me using MUTT.
Until now, I've done:
#!/bin/sh
psql -d roaming -U thdroaming -o saida.txt << EOF
\d
\pset border 2
SELECT central, imsi, mapver, camel, nrrg, plmn, inoper, natms, cba, cbaz, stall, ownms, imsi_translation, forbrat FROM vw_erros_mgisp_totalizador
EOF
My problem is:
The .txt "saida.txt" is bringing me info about the database, as follows:
Lista de relações
Esquema | Nome | Tipo | Dono
---------+----------------------------------+-----------+------------
public | apns | tabela | jmsilva
public | config_imsis_centrais | tabela | thdroaming
public | config_imsis_sgsn | tabela | postgres
(3 Registers)
+---------+---------+----------+---------+---------+--------+------------+-------+---------+----------+-------+-------+------------------+-----------+
| central | imsi | mapver | camel | nrrg | plmn | inoper | natms | cba | cbaz | stall | ownms | imsi_translation | forbrat |
+---------+---------+----------+---------+---------+--------+------------+-------+---------+----------+-------+-------+------------------+-----------+
| MCTA02 | 20210 | | | | | INOPER-127 | | | | | | | |
| MCTA02 | 20404 | | | | | INOPER-127 | | | | | | | |
| MCTA02 | 20408 | | | | | INOPER-127 | | | | | | | |
| MCTA02 | 20412 | | | | | INOPER-127 | | | | | | | |
.
.
.
How could I make the first table not to be imported to the .txt?
Remove the '\d' portion of the script which causing listing the tables in the DB you see at the top of your output. So your script will become:
#!/bin/sh
psql -d roaming -U thdroaming -o saida.txt << EOF
\pset border 2
SELECT central, imsi, mapver, camel, nrrg, plmn, inoper, natms, cba, cbaz, stall, ownms, imsi_translation, forbrat FROM vw_erros_mgisp_totalizador
EOF
To get the output to appear CSV formatted in a file named /tmp/output.csv do you can do the following:
#!/bin/sh
psql -d roaming -U thdroaming -o saida.txt << EOF
\pset border 2
COPY (SELECT central, imsi, mapver, camel, nrrg, plmn, inoper, natms, cba, cbaz, stall, ownms, imsi_translation, forbrat FROM vw_erros_mgisp_totalizador) TO '/tmp/output.csv' WITH (FORMAT CSV)
EOF