SQL and relational algebra - sql

I've got some problems which I can't work out. Here is the scheme:
sch(branch)=(branch_Nr,town) (Key: branch_Nr)
sch(account)=(account_Nr,ballance) (Key: account_Nr)
sch(manages)=(account_Nr,branch_Nr) (Key: account_Nr, branch_Nr)
sch(customer)=(customer_Nr,Name,street,place) (Key: customer_Nr)
sch(mentors)=(branch_Nr,customer_Nr) (Key: customer_Nr)
sch(opens)=(customer_Nr,account_Nr) (Key: account_Nr)
the task is to get with relational algebra: get all customers with 2 different accounts. I tried the solution:
πname(Customer) |X| σ k1!=k2 (πk1 <- account_Nr (account) X πk2 <- account_Nr (account))
But this doesnt work does it? I feel like im missing sth here.
Second task is: to get 2 customers with two different accounts, which are managed by different branches in SQL:
I tried it with:
CREATE VIEW N AS
SELECT account_Nr
FROM account
GROUP BY accountNr
HAVING TOTAL = 2
With this I wanted to make it more structured so I used a view before I actually use the real selection task. But im kinda stuck here already. The problem is that I want everybody who got 2 accounts which are at different branches. This means that he can still have more than 2 accounts. But with this I ignore that. And i am not so sure how to proceed after that as well. These are one of the problems I try to prepare myself for an upcoming test. I would really appreciate help! kinda stuck here.

Related

Rails joins query killed or just too slow. Please recommend the proper way to create queries

I am having trouble properly creating query with joins. It starts to talk to server but it ends up clogged and saying "killed" (in Rails console)
I have to models.
One is 'User', the other one is 'Availability'
Some users will open availabilities in 2 weeks. And I'd like to fetch 50 users with this condition with page variable.(because there will be many of them and I'd like to fetch 50 on every call)
Availability has two columns: user_id and start_time(datetime)
And the association is that user has many availabilities.
The query looks like the below.
people = User
.where(role: SOMETHING)
.includes(:availabilities)
.joins(:availabilities)
.where('availabilities.start_time > ?', Time.now)
.where('availabilities.start_time < ?', Time.now + 2.weeks)
.limit(5)
.offset(50 * (n-1))
where n is integer from 1
However, this query never gives me result on the production (in the console it's killed. Before the console kills the process, when querying, it shows normal query statement (sql 30ms for instance) forever. In local, where data is small, it works. Are there anything missing here?
Please give me any advice!!
And weird thing is ,
people = User
.where(role: SOMETHING)
.includes(:availabilities)
.joins(:availabilities)
.limit(5)
.offset(50 * (n-1))
then if
people.map(&:id) => [18,18,18,18,18]
which means people is inappropriately fetched. I am just confused here..!
Includes availabilities will generate availability model instances after querying.
If availability rows are so many, it will cost a lot of time.
If you won't use availabilities after querying, please try
people = User
.where(role: ROLES)
.joins(:availabilities)
.where(availabilities: {start_time: (Time.now)..(2.weeks.from_now)})
.offset(50 * (n-1))
.limit(5)
I kind of find the way to work it:
people = User
.where(role: ROLES)
.joins(:availabilities)
.where(availabilities: { start_time: (Time.now)..(2.weeks.from_now) })
.distinct
.offset(50 * (n-1))
.limit(5)
Then:
people.map(&:id), => [x,y,z,l,m]

Trying to refactor Rails 4.2 scope

I have updated this question
I have the following SQL scope in a RAILS 4 app, it works, but has a couple of issues.
1) Its really RAW SQL and not the rails way
2) The string interpolation opens up risks with SQL injection
here is what I have:
scope :not_complete -> (user_id) { joins("WHERE id NOT IN
(SELECT modyule_id FROM completions WHERE user_id = #{user_id})")}
The relationship is many to many, using a join table called completions for matching id(s) on relationships between users and modyules.
any help with making this Rails(y) and how to set this up to take the arg of user_id with out the risk, so I can call it like:
Modyule.not_complete("1")
Thanks!
You should have added few info about the models and their assocciation, anyways here's my trial, might have some errors because I don't know if the assocciation is one to many or many to many.
scope :not_complete, lambda do |user_id|
joins(:completion).where.not( # or :completions ?
id: Completion.where(user_id: user_id).pluck(modyule_id)
)
end
PS: I turned it into multi line just for readability, you can change it back to a oneline if you like.

orientdb sql update edge?

I have been messing around with orientdb sql, and I was wondering if there is a way to update an edge of a vertex, together with some data on it.
assuming I have the following data:
Vertex: Person, Room
Edge: Inside (from Person to Room)
something like:
UPDATE Persons SET phone=000000, out_Inside=(
select #rid from Rooms where room_id=5) where person_id=8
obviously, the above does not work. It throws exception:
Error: java.lang.ClassCastException: com.orientechnologies.orient.core.id.ORecordId cannot be cast to com.orientechnologies.orient.core.db.record.ridbag.ORidBag
I tried to look at the sources at github searching for a syntax for bag with 1 item,
but couldn't find any (found %, but that seems to be for serialization no for SQL).
(1) Is there any way to do that then? how do I update a connection? Is there even a way, or am I forced to create a new edge, and delete the old one?
(2) When writing this, it came to my mind that perhaps edges are not the way to go in this case. Perhaps I should use a LINK instead. I have to say i'm not sure when to use which, or what are the implications involved in using any of them. I did found this though:
https://groups.google.com/forum/#!topic/orient-database/xXlNNXHI1UE
comment 3 from the top, of Lvc#, where he says:
"The suggested way is to always create an edge for relationships"
Also, even if I should use a link, please respond to (1). I would be happy to know the answer anyway.
p.s.
In my scenario, a person can only be at one room. This will most likely not change in the future. Obviously, the edge has the advantage that in case I might want to change it (however improbable that may be), it will be very easy.
Solution (partial)
(1) The solution was simply to remove the field selection. Thanks for Lvca for pointing it out!
(2) --Still not sure--
CREATE EDGE and DELETE EDGE commands have this goal: avoid the user to fight with underlying structure.
However if you want to do it (a little "dirty"), try this one:
UPDATE Persons SET phone=000000, out_Inside=(
select from Rooms where room_id=5) where person_id=8
update EDGE Custom_Family_Of_Custom
set survey_status = '%s',
apply_source = '%s'
where #rid in (
select level1_e.#rid from (
MATCH {class: Custom, as: custom, where: (custom_uuid = '%s')}.bothE('Custom_Family_Of_Custom') {as: level1_e} .bothV('Custom') {as: level1_v, where: (custom_uuid = '%s')} return level1_e
)
)
it works well

phalcon querybuilder total_items always returns 1

I make a query via createBuilder() and when executing it (getQuery()->execute()->toArray())
I got 10946 elements. I want to paginate it, so I pass it to:
$paginator = new \Phalcon\Paginator\Adapter\QueryBuilder(array(
"builder" => $builder,
"limit" => $limit,
"page" => $current_page
));
$limit is 25 and $current_page is 1, but when doing:
$paginator->getPaginate();
$page->total_items;
returns 1.
Is that a bug or am I missing something?
UPD: it seems like when counting items it uses created sql with limit. There is no difference what limit is, limit divided by items per page always equals 1. I might be mistaken.
UPD2: Colleague helped me to figure this out, the bug was in the query phalcon produces: count() of the group by counts grouped elements. So a workaround looks like:
$dataCount = $builder->getQuery()->execute()->count();
$page->next = $page->current + 1;
$page->before = $page->current - 1 > 0 ? $page->current - 1 : 1;
$page->total_items = $dataCount;
$page->total_pages = ceil($dataCount / 100);
$page->last = $page->total_pages;
I know this isn't much of an answer but this is most likely to be a bug. Great guys at Phalcon took on a massive job that is too big to do it properly in their little free time and things like PHQL, Volt and other big but non-core components do not receive as much attention as we'd like. Also given that most time in the past 6 months was spent on v2 there are nearly 500 bugs about stuff like that and it's counting. I came across considerable issues in ORM, Volt, Validation and Session, which in the end made me stick to other not as cool but more proven solutions. When v2 comes out I'm sure all attention will on the bug list and testing, until then we are mostly on our own. Given that it's all C right now, only a few enthusiast get involved, with v2 this will also change.
If this is the only problem you are hitting, the best approach is to update your query to get the information you need yourself without getPaginate().

Rails 3 selecting only values

In rails 3, I would like to do the following:
SomeModel.where(:some_connection_id => anArrayOfIds).select("some_other_connection_id")
This works, but i get the following from the DB:
[{"some_other_connection_id":254},{"some_other_connection_id":315}]
Now, those id-s are the ones I need, but I am uncapable of making a query that only gives me the ids. I do not want to have to itterate over the resulst, only to get those numbers out. Are there any way for me to do this with something like :
SomeModel.where(:some_connection_id => anArrayOfIds).select("some_other_connection_id").values()
Or something of that nautre?
I have been trying with the ".select_values()" found at Git-hub, but it only returns "some_other_connection_id".
I am not an expert in rails, so this info might be helpful also:
The "SomeModel" is a connecting table, for a many-to-many relation in one of my other models. So, accually what I am trying to do is to, from the array of IDs, get all the entries from the other side of the connection. Basicly I have the source ids, and i want to get the data from the models with all the target ids. If there is a magic way of getting these without me having to do all the sql myself (with some help from active record) it would be really nice!
Thanks :)
Try pluck method
SomeModel.where(:some => condition).pluck("some_field")
it works like
SomeModel.where(:some => condition).select("some_field").map(&:some_field)
SomeModel.where(:some_connection_id => anArrayOfIds).select("some_other_connection_id").map &:some_other_connection_id
This is essentially a shorthand for:
results = SomeModel.where(:some_connection_id => anArrayOfIds).select("some_other_connection_id")
results.map {|row| row.some_other_connection_id}
Look at Array#map for details on map method.
Beware that there is no lazy loading here, as it iterates over the results, but it shouldn't be a problem, unless you want to add more constructs to you query or retrieve some associated objects(which should not be the case as you haven't got the ids for loading the associated objects).