Repository: kayak/pypika (python)

Issue:
additional Join functionality 
- It would be a nice convenience function just to specify a string or list of strs if the column(s) to join on are the same in both tables. e.g. from_(t1).join(t2).on('c1')

- it's not clear how I can construct a join USING clause "... from t1 join t2 USING (c1, c2)"

i'm happy to contribute if this is not yet available but you think would be helpful

I'm sorry the docs don't show a preferred method of getting in touch. please suggest most appropriate communication channel. You can look me up as "CJ Lee" from London on linkedin

P.S. love this package thanks for this

Pull request description:
Fixes #36 Added a join on_field function
Added a convenience function `on_field` for joining when the from table and join tables share the column name(s)

Patch:
diff --git a/README.rst b/README.rst
index 3bba5bd..32d9ee5 100644
--- a/README.rst
+++ b/README.rst
@@ -315,6 +315,31 @@ Example of a join using `ON`
 
     SELECT "history".* FROM "history" JOIN "customers" ON "history"."customer_id"="customers"."id" WHERE "customers"."id"=5
 
+As a shortcut, the ``Query.join().on_field()`` function is provided for joining the (first) table in the ``FROM`` clause
+with the joined table when the field name(s) are the same in both tables.
+
+Example of a join using `ON`
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: python
+
+    history, customers = Tables('history', 'customers')
+    q = Query.from_(history).join(
+        customers
+    ).on_field(
+        'customer_id', 'group'
+    ).select(
+        history.star
+    ).where(
+        customers.group == 'A'
+    )
+
+
+.. code-block:: sql
+
+    SELECT "history".* FROM "history" JOIN "customers" ON "history"."customer_id"="customers"."customer_id" AND "history"."group"="customers"."group" WHERE "customers"."group"='A'
+
+
 
 Example of a join using `USING`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/pypika/queries.py b/pypika/queries.py
index 3feffe2..36aa665 100644
--- a/pypika/queries.py
+++ b/pypika/queries.py
@@ -625,8 +625,21 @@ class Joiner(object):
 
     def on(self, criterion):
         if criterion is None:
-            raise JoinException("Parameter 'on' is required when joining a "
-                                "{type} but was not supplied.".format(type=self.type_label))
+            raise JoinException("Parameter 'criterion' is required for a "
+                                "{type} JOIN but was not supplied.".format(type=self.type_label))
+
+        self.query.do_join(JoinOn(self.item, self.how, criterion))
+        return self.query
+
+    def on_field(self, *fields):
+        if not fields:
+            raise JoinException("Parameter 'fields' is required for a "
+                                "{type} JOIN but was not supplied.".format(type=self.type_label))
+
+        criterion = None
+        for field in fields:
+            consituent = Field(field, table=self.query._from[0]) == Field(field, table=self.item)
+            criterion = consituent if criterion is None else criterion & consituent
 
         self.query.do_join(JoinOn(self.item, self.how, criterion))
         return self.query


Test patch:
diff --git a/pypika/tests/test_joins.py b/pypika/tests/test_joins.py
index 7667ced..405e8f2 100644
--- a/pypika/tests/test_joins.py
+++ b/pypika/tests/test_joins.py
@@ -31,6 +31,23 @@ class JoinTypeTests(unittest.TestCase):
         self.assertEqual('SELECT * FROM "abc" JOIN "efg" ON "abc"."foo"="efg"."bar"', str(query))
         self.assertEqual('SELECT * FROM "abc" JOIN "efg" ON "abc"."foo"="efg"."bar"', str(query_explicit))
 
+    def test_join_on_field_single(self):
+        query = Query.from_(self.table0).join(self.table1).on_field("foo").select('*')
+        self.assertEqual('SELECT * FROM "abc" JOIN "efg" ON "abc"."foo"="efg"."foo"', str(query))
+
+    def test_join_on_field_multi(self):
+        query = Query.from_(self.table0).join(self.table1).on_field("foo", "bar").select('*')
+        self.assertEqual('SELECT * FROM "abc" JOIN "efg" ON "abc"."foo"="efg"."foo" '
+                         'AND "abc"."bar"="efg"."bar"', str(query))
+
+    def test_join_on_field_multi_with_extra_join(self):
+        query = Query.from_(self.table0)\
+            .join(self.hij).on_field("buzz")\
+            .join(self.table1).on_field("foo", "bar").select('*')
+
+        self.assertEqual('SELECT * FROM "abc" JOIN "hij" ON "abc"."buzz"="hij"."buzz" '
+                         'JOIN "efg" ON "abc"."foo"="efg"."foo" AND "abc"."bar"="efg"."bar"', str(query))
+
     def test_join_using_string_field_name(self):
         query = Query.from_(self.table0).join(self.table1).using('id').select('*')