outer join added
git-svn-id: http://galileo.dmi.unict.it/svn/relational/trunk@10 014f5005-505e-4b48-8d0a-63407b615a7c
This commit is contained in:
parent
0c11969722
commit
7042bef744
89
relation.py
89
relation.py
@ -54,6 +54,18 @@ class relation (object):
|
|||||||
fp=file(filename,'w')
|
fp=file(filename,'w')
|
||||||
fp.write(res)
|
fp.write(res)
|
||||||
fp.close()
|
fp.close()
|
||||||
|
def rearrange(self,other):
|
||||||
|
'''If two relations share the same attributes in a different order, this method
|
||||||
|
will use projection to make them have the same attributes' order.
|
||||||
|
It is not exactely related to relational algebra. Just a method used
|
||||||
|
internally.
|
||||||
|
Will return None if they don't share the same attributes'''
|
||||||
|
if (self.__class__!=other.__class__):
|
||||||
|
return None
|
||||||
|
if self.header.sharedAttributes(other.header) == len(self.header.attributes) == len(other.header.attributes):
|
||||||
|
return other.projection(list(self.header.attributes))
|
||||||
|
return None
|
||||||
|
|
||||||
def selection(self,expr):
|
def selection(self,expr):
|
||||||
'''Selection, expr must be a valid boolean expression, can contain field names,
|
'''Selection, expr must be a valid boolean expression, can contain field names,
|
||||||
constant, math operations and boolean ones.'''
|
constant, math operations and boolean ones.'''
|
||||||
@ -150,6 +162,7 @@ class relation (object):
|
|||||||
Will return an empty one if there are no common items.
|
Will return an empty one if there are no common items.
|
||||||
Will return None if headers are different.
|
Will return None if headers are different.
|
||||||
It is possible to use projection and rename to make headers match.'''
|
It is possible to use projection and rename to make headers match.'''
|
||||||
|
other=self.rearrange(other) #Rearranges attributes' order
|
||||||
if (self.__class__!=other.__class__)or(self.header!=other.header):
|
if (self.__class__!=other.__class__)or(self.header!=other.header):
|
||||||
return None
|
return None
|
||||||
newt=relation()
|
newt=relation()
|
||||||
@ -167,6 +180,7 @@ class relation (object):
|
|||||||
Will return an empty one if the second is a superset of first.
|
Will return an empty one if the second is a superset of first.
|
||||||
Will return None if headers are different.
|
Will return None if headers are different.
|
||||||
It is possible to use projection and rename to make headers match.'''
|
It is possible to use projection and rename to make headers match.'''
|
||||||
|
other=self.rearrange(other) #Rearranges attributes' order
|
||||||
if (self.__class__!=other.__class__)or(self.header!=other.header):
|
if (self.__class__!=other.__class__)or(self.header!=other.header):
|
||||||
return None
|
return None
|
||||||
newt=relation()
|
newt=relation()
|
||||||
@ -185,6 +199,7 @@ class relation (object):
|
|||||||
Will not insert tuplicated items.
|
Will not insert tuplicated items.
|
||||||
Will return None if headers are different.
|
Will return None if headers are different.
|
||||||
It is possible to use projection and rename to make headers match.'''
|
It is possible to use projection and rename to make headers match.'''
|
||||||
|
other=self.rearrange(other) #Rearranges attributes' order
|
||||||
if (self.__class__!=other.__class__)or(self.header!=other.header):
|
if (self.__class__!=other.__class__)or(self.header!=other.header):
|
||||||
return None
|
return None
|
||||||
newt=relation()
|
newt=relation()
|
||||||
@ -198,6 +213,80 @@ class relation (object):
|
|||||||
if e not in newt.content:
|
if e not in newt.content:
|
||||||
newt.content.append(list(e))
|
newt.content.append(list(e))
|
||||||
return newt
|
return newt
|
||||||
|
def outer(self,other):
|
||||||
|
'''Does a left and a right outer join and returns their union.'''
|
||||||
|
a=self.outer_right(other)
|
||||||
|
b=self.outer_left(other)
|
||||||
|
print a
|
||||||
|
print b
|
||||||
|
|
||||||
|
return a.union(b)
|
||||||
|
|
||||||
|
def outer_right(self,other):
|
||||||
|
'''Same as left join, with swapped parameters'''
|
||||||
|
return self.outer_left(other,True)
|
||||||
|
|
||||||
|
def outer_left(self,other,swap=False):
|
||||||
|
'''Outer left join. Considers self as left and param as right. If the
|
||||||
|
tuple has no corrispondence, empty attributes are filled with a "---"
|
||||||
|
string. This is due to the fact that empty string or a space would cause
|
||||||
|
problems when saving the relation.
|
||||||
|
Just like natural join, it works considering shared attributes.
|
||||||
|
If swap is True, it will behave as a right join'''
|
||||||
|
|
||||||
|
if swap:
|
||||||
|
tmp=other
|
||||||
|
other=self
|
||||||
|
self=tmp
|
||||||
|
|
||||||
|
shared=[]
|
||||||
|
for i in self.header.attributes:
|
||||||
|
if i in other.header.attributes:
|
||||||
|
shared.append(i)
|
||||||
|
|
||||||
|
newt=relation() #Creates the new relation
|
||||||
|
|
||||||
|
#Adds all the attributes of the 1st relation
|
||||||
|
newt.header=header(list(self.header.attributes))
|
||||||
|
|
||||||
|
#Adds all the attributes of the 2nd, when non shared
|
||||||
|
for i in other.header.attributes:
|
||||||
|
if i not in shared:
|
||||||
|
newt.header.attributes.append(i)
|
||||||
|
#Shared ids of self
|
||||||
|
sid=self.header.getAttributesId(shared)
|
||||||
|
#Shared ids of the other relation
|
||||||
|
oid=other.header.getAttributesId(shared)
|
||||||
|
|
||||||
|
#Non shared ids of the other relation
|
||||||
|
noid=[]
|
||||||
|
for i in range(len(other.header.attributes)):
|
||||||
|
if i not in oid:
|
||||||
|
noid.append(i)
|
||||||
|
|
||||||
|
for i in self.content:
|
||||||
|
#Tuple partecipated to the join?
|
||||||
|
added=False
|
||||||
|
for j in other.content:
|
||||||
|
match=True
|
||||||
|
for k in range(len(sid)):
|
||||||
|
match=match and ( i[sid[k]]== j[oid[k]])
|
||||||
|
|
||||||
|
if match:
|
||||||
|
item=list(i)
|
||||||
|
for l in noid:
|
||||||
|
item.append(j[l])
|
||||||
|
|
||||||
|
newt.content.append(item)
|
||||||
|
added=True
|
||||||
|
#If it didn't partecipate, adds it
|
||||||
|
if not added:
|
||||||
|
item=list(i)
|
||||||
|
for l in range(len(noid)):
|
||||||
|
item.append("---")
|
||||||
|
newt.content.append(item)
|
||||||
|
|
||||||
|
return newt
|
||||||
|
|
||||||
def join(self,other):
|
def join(self,other):
|
||||||
'''Natural join, joins on shared attributes (one or more). If there are no
|
'''Natural join, joins on shared attributes (one or more). If there are no
|
||||||
|
@ -15,3 +15,4 @@ id skill
|
|||||||
7 Python
|
7 Python
|
||||||
7 C
|
7 C
|
||||||
7 PHP
|
7 PHP
|
||||||
|
9 Java
|
Loading…
x
Reference in New Issue
Block a user