Skip to content
This repository has been archived by the owner on Nov 22, 2018. It is now read-only.

Multiple joins? #136

Open
devfacet opened this issue Sep 13, 2016 · 12 comments
Open

Multiple joins? #136

devfacet opened this issue Sep 13, 2016 · 12 comments
Assignees
Labels

Comments

@devfacet
Copy link

Is there a support for multiple joins? I couldn't make it work and want make sure whether it's supported or not.

@cznic cznic added the question label Sep 13, 2016
@cznic cznic self-assigned this Sep 13, 2016
@cznic
Copy link
Owner

cznic commented Sep 13, 2016

For example

$ ql 'create table a (i int, key int)'
$ ql 'create table b (i int, key int)'
$ ql 'create table c (i int)'
$ ql 'insert into c values(100)'
$ ql 'insert into b select 200, id() from c'
$ ql 'insert into a select 300, id() from b'
$ ql -fld 'select * from a, b, c where a.key == id(b) && b.key == id(c)'
"a.i", "a.key", "b.i", "b.key", "c.i"
300, 2, 200, 1, 100
$ 

@devfacet
Copy link
Author

Sorry for not being more specific. I was talking about {LEFT,RIGHT,FULL} [OUTER] JOIN

for example;

SELECT
  product.key,
  category.name,
  condition.name
FROM
  product
LEFT JOIN category ON category.key = product.catkey
LEFT JOIN condition ON condition.key = product.condkey;

"product.key", "category.name", "condition.name"
1               foo              bar
2               hello            <nil>
3               <nil>            baz
4               <nil>            <nil>

@devfacet
Copy link
Author

fyi - currently I'm using temporary tables in a transaction block. Basically joining tables one by one and it's little bit extra work.

@cznic
Copy link
Owner

cznic commented Sep 14, 2016

The documented grammar does not allow nesting of the join clause. That should be fixed (PRs weclome 😄).

AFAICT, something like this should work

drop table if exists category;
drop table if exists condition;
drop table if exists product;

create table category (key int, name string);
create table condition (key int, name string);
create table product (key int, catkey int, condkey int);

insert into category values (1, "foo"), (2, "hello");
insert into condition values (1, "bar"), (2, "baz");
insert into product values (1, 1, 1), (2, 2, null), (3, null, 2), (4, null, null);

select *
from
  (select
   product.key as product_key,
   category.name as category_name,
   product.condkey as product_condkey
   from
     product
   left join category on category.key == product.catkey)
left join condition on condition.key == product_condkey;

but it does not work

$ ql -fld < join.ql 
"", "", "", "condition.key", "condition.name"
2016/09/14 12:14:38 unknown field product_condkey
$ 

The problem seems to be that the inner join does not output the proper field names so the outer join fails. I will fill a separate issue for this.

@devfacet
Copy link
Author

Yes I tired the way you tired and it didn't worked. I thought it wasn't supported. That's why I'm joining them one by one by creating temporary tables. Unfortunately I'm quite busy for a PR atm. But I will keep it in my mind and try it when I have a chance. Sorry about that :(

@gernest
Copy link
Collaborator

gernest commented Apr 10, 2017

@cznic @devfacet I would like to look into this. Is this still an I issue.

If thee is already an ongoing effort, I will be more than happy to help. Unfortunate I suck at SQL so, insight and direction where to look for stuff will be highly appreciated.

Thanks.

@gernest
Copy link
Collaborator

gernest commented May 4, 2017

gentle ping @cznic

can yuo please tell me what is the expected result from this ?

drop table if exists category;
drop table if exists condition;
drop table if exists product;

create table category (key int, name string);
create table condition (key int, name string);
create table product (key int, catkey int, condkey int);

insert into category values (1, "foo"), (2, "hello");
insert into condition values (1, "bar"), (2, "baz");
insert into product values (1, 1, 1), (2, 2, null), (3, null, 2), (4, null, null);

select *
from
  (select
   product.key as product_key,
   category.name as category_name,
   product.condkey as product_condkey
   from
     product
   left join category on category.key == product.catkey)
left join condition on condition.key == product_condkey;

I'm looking at this issue

@cznic
Copy link
Owner

cznic commented May 4, 2017

can yuo please tell me what is the expected result from this ?

I'm not completely sure, unfortunately. Can you please try what, with required modifications, the results are in some other RDBMS? We would then at least know what the test cases should test against...

@gernest
Copy link
Collaborator

gernest commented May 4, 2017

@cznic no problem . I think I found out a way to solve this.

I fixed the fields now i get

"product_key", "category_name", "product_condkey", "condition.key", "condition.name"

I will cleanup and write more details after more tests

@gernest
Copy link
Collaborator

gernest commented May 4, 2017

another gentle ping @cznic @devfacet

On my dev branch

$ ql -fld < join.ql
"product_key", "category_name", "product_condkey", "condition.key", "condition.name"
4, <nil>, <nil>, <nil>, <nil>
3, <nil>, 2, 2, "baz"
2, "hello", <nil>, <nil>, <nil>
1, "foo", 1, 1, "bar"

contents of join.ql

drop table if exists category;
drop table if exists condition;
drop table if exists product;

create table category (key int, name string);
create table condition (key int, name string);
create table product (key int, catkey int, condkey int);

insert into category values (1, "foo"), (2, "hello");
insert into condition values (1, "bar"), (2, "baz");
insert into product values (1, 1, 1), (2, 2, null), (3, null, 2), (4, null, null);

select *
from
  (select
   product.key as product_key,
   category.name as category_name,
   product.condkey as product_condkey
   from
     product
   left join category on category.key == product.catkey)
left join condition on condition.key == product_condkey;

@devfacet
Copy link
Author

devfacet commented May 5, 2017

@gernest : After this issue (as well as some other performance issues) I gave up this package and decided to use go-sqlite3 package . The only annoying thing with go-sqlite3 is that it is a cgo package. That being said @cznic is working on something else may solve that issue. See https://github.com/cznic/sqlite

If you need an embedded SQL database in Go (for production purposes) then either use https://github.com/mattn/go-sqlite3 or try https://github.com/cznic/ql (I'll try it at one point.)

@gernest
Copy link
Collaborator

gernest commented May 5, 2017

@devfacet thanks for the recommendation. At the moment I would like to improve ql hopefully it will be production ready one day.

gernest added a commit to gernest/ql that referenced this issue May 5, 2017
Closes cznic#137
Context cznic#136

This PR make sure the field names for results nested select are set properly.

The observation from postgresql  shows that  for the following sql.

```sql
      BEGIN TRANSACTION;
		CREATE TABLE department (
		    DepartmentID   integer,
			DepartmentName text
		);

		INSERT INTO department (DepartmentID,DepartmentName) VALUES
			(31, 'Sales'),
			(33, 'Engineering'),
			(34, 'Clerical'),
			(35, 'Marketing');

		CREATE TABLE employee (
			LastName     text,
			DepartmentID integer
		);

		INSERT INTO employee VALUES
			('Rafferty', 31),
			('Jones', 33),
			('Heisenberg', 33),
			('Robinson', 34),
			('Smith', 34),
			('Williams', NULL);

     COMMIT;
```

```
gernest=# select * from (select * from employee) as a,(select * from department ) as d  order by d.DepartmentID  desc;
  lastname  | departmentid | departmentid | departmentname
------------+--------------+--------------+----------------
 Rafferty   |           31 |           35 | Marketing
 Robinson   |           34 |           35 | Marketing
 Williams   |              |           35 | Marketing
 Jones      |           33 |           35 | Marketing
 Smith      |           34 |           35 | Marketing
 Heisenberg |           33 |           35 | Marketing
 Jones      |           33 |           34 | Clerical
 Williams   |              |           34 | Clerical
 Robinson   |           34 |           34 | Clerical
 Heisenberg |           33 |           34 | Clerical
 Rafferty   |           31 |           34 | Clerical
 Smith      |           34 |           34 | Clerical
 Smith      |           34 |           33 | Engineering
 Jones      |           33 |           33 | Engineering
 Williams   |              |           33 | Engineering
 Heisenberg |           33 |           33 | Engineering
 Robinson   |           34 |           33 | Engineering
 Rafferty   |           31 |           33 | Engineering
 Robinson   |           34 |           31 | Sales
 Jones      |           33 |           31 | Sales
 Heisenberg |           33 |           31 | Sales
 Rafferty   |           31 |           31 | Sales
 Smith      |           34 |           31 | Sales
 Williams   |              |           31 | Sales
(24 rows)
```

Previously the names were set to empty strings .
gernest added a commit to gernest/ql that referenced this issue May 5, 2017
Closes cznic#137
Context cznic#136

This PR make sure the field names for results nested select are set properly.

Previously the names were set to empty strings .
gernest added a commit to gernest/ql that referenced this issue May 5, 2017
Closes cznic#137
Context cznic#136

This PR make sure the field names for results nested select are set properly.

Previously the names were set to empty strings .
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants