Hello
I almost tried every combination of getting these views to work. The most difficult thing is, that I do use three connection between nodes:
node.vid -> author.vid for Version
and
mybook.authorid -> author.id (1:1 connection between author and mybook)
and
bookcollection.id -> (mybookbookcollectionrel.bookcollectionid | mybookcollectionrel.mybookid)
-> mybook.id (n:m relation between mybook and bookcollection over a relation table)
The correct SQL generated by views 2.0 would be the following:
SELECT author.name AS authorname, bookcollection.vid AS bookcollectionvid, bookcollection.name AS bookcollectionname, mybook.vid AS mybook_vid, mybook.title AS mybooktitle
FROM node node
LEFT JOIN author author ON node.vid = author.vid
LEFT JOIN bookcollection bookcollection_node ON node.vid = bookcollection_node.vid
LEFT JOIN mybook mybook_node ON node.vid = mybook_node.vid
INNER JOIN mybook mybook ON mybook.authorid = author.id
LEFT JOIN mybookbookcollectionrel mybookbookcollectionrel ON mybook.id = mybookbookcollectionrel.mybookid
LEFT JOIN bookcollection bookcollection ON bookcollection.id = mybookbookcollectionrel.bookcollectionid
I need 3 Joins on the node and the entites mybook, bookcollection, and author over vid (ensures newest version)
Then I need an INNER JOIN between mybook and author (getting all books of an author)
And at least I need a double join over the relation table: mybook.id -> mybookbookcollectionrel -> bookcollection.id
(getting all bookcollection of mybooks)
Unfortunately the SQL Code generated is always faulty. Where is my fault in the mymodule.views.inc.
I commented out all the joins because they had no influence on the resulting SQL Query statement.
<?
/**
CREATE TABLE `author` (
`nid` int(10) NOT NULL,
`vid` int(10) NOT NULL,
`id` int(10) NOT NULL,
`name` varchar(120) NOT NULL,
PRIMARY KEY (`id`),
KEY `vid` (`vid`),
KEY `nid` (`nid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
CREATE TABLE `bookcollection` (
`nid` int(10) NOT NULL,
`vid` int(10) NOT NULL,
`id` bigint(20) NOT NULL,
`authorid` bigint(20) NOT NULL,
`name` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
KEY `authorid` (`authorid`),
KEY `nid` (`nid`),
KEY `vid` (`vid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `mybookbookcollectionrel` (
`mybookid` bigint(20) NOT NULL default '0',
`bookcollectionid` bigint(20) NOT NULL default '0',
KEY `bookcollectionid` (`bookcollectionid`),
KEY `mybookid` (`mybookid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `mybook` (
`nid` int(10) NOT NULL,
`vid` int(10) NOT NULL,
`id` bigint(20) NOT NULL,
`authorid` bigint(20) NOT NULL default '0',
`title` varchar(150) NOT NULL,
`content` text,
PRIMARY KEY (`id`),
KEY `authorid` (`authorid`),
KEY `nid` (`nid`),
KEY `vid` (`vid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
//---- Notations ---//
- an author can have on or more books
- books can be grouped into bookcollections
- a bookcollection are mybook from the same author
- mybook can be in several more bookcollection.
- a bookcollection consists of one ore more mybooks
The link between mybook and bookcollection is done by mybookbookcollectionrel which is only a relation-table
- a mybook is linked 1:1 with an author
- a mybook collection is linked with an author
//---- SQL Query Test -----//
The goal is a view that looks like that:
authorname | bookcollection_name | mybook_title |
AAA | 1 | Title 1
AAA | 1 | Title 2
AAA | 1 | Title 3
AAA | 1 | Title 4
AAA | 2 | Title 1
AAA | 2 | Title 2
AAA | 2 | Title 5
AAA | 2 | Title 6
With arguments I could show only one bookcollection (argument on bookcollectionid)
//---- SQL Queries from Views 2.0 ---- //
SELECT node.nid AS nid,
author_mybook.name AS author_mybook_name,
bookcollection.name AS bookcollection_name,
mybook.vid AS mybook_vid,
mybook.title AS mybook_title
FROM node node
LEFT JOIN mybook mybook ON node.vid = mybook.vid
INNER JOIN author author_mybook ON mybook.authorid = author_mybook.id
LEFT JOIN mybook mybook_mybookbookcollectionrel ON .mybookid = mybook_mybookbookcollectionrel.
LEFT JOIN bookcollection bookcollection ON node.vid = bookcollection.vid
WHERE bookcollection.vid = 201
The SQL Code is not valid that is generated by Views 2.0. There are missing table names and fields.
//---- SQL Queries that would be correct --//
SELECT author.name AS authorname, bookcollection.vid AS bookcollectionvid, bookcollection.name AS bookcollectionname, mybook.vid AS mybook_vid, mybook.title AS mybooktitle
FROM node node
LEFT JOIN author author ON node.vid = author.vid
LEFT JOIN bookcollection bookcollection_node ON node.vid = bookcollection_node.vid
LEFT JOIN mybook mybook_node ON node.vid = mybook_node.vid
INNER JOIN mybook mybook ON mybook.authorid = author.id
LEFT JOIN mybookbookcollectionrel mybookbookcollectionrel ON mybook.id = mybookbookcollectionrel.mybookid
LEFT JOIN bookcollection bookcollection ON bookcollection.id = mybookbookcollectionrel.bookcollectionid
I need 3 Joins on the node and the entites mybook, bookcollection, and author
Then I need an INNER JOIN between mybook and author
And at least I need a double join over the relation table: mybook.id -> mybookbookcollectionrel -> bookcollection.id
*/
/**
* Implementation of hook_views_data()
*/
function mymodule_author_views_data() {
$data = array();
// Basic table information.
// Define the base group of this table. Fields that don't
// have a group defined will go into this field by default.
$data['author']['table']['group'] = t('mymodule');
$data['author']['table']['base'] = array(
'field' => 'id',
'title' => t('Bookcollection'),
);
// For other base tables, explain how we join
$data['author']['table']['join'] = array(
// author links to node directly via vid.
'node' => array(
'left_field' => 'vid',
'field' => 'vid',
),
);
///ALBUM
$data['bookcollection']['table']['group'] = t('mymodule');
// For other base tables, explain how we join
$data['bookcollection']['table']['join'] = array(
// author links to node directly via vid.
'node' => array(
'left_field' => 'vid',
'field' => 'vid',
),
/*
'author' => array(
'left_field' => 'authorid',
'field' => 'id',
),
'mybookbookcollectionrel' => array(
'left_field' => 'id',
'field' => 'bookcollectionid',
),
'mybook' => array(
'left_table' => 'mybookbookcollectionrel',
'left_field' => 'bookcollectionid',
'field' => 'id',
),*/
);
//SONG
$data['mybook']['table']['group'] = t('mymodule');
// For other base tables, explain how we join
$data['mybook']['table']['join'] = array(
// author links to node directly via vid.
'node' => array(
'left_field' => 'vid',
'field' => 'vid',
),
/*
'author' => array(
'left_field' => 'id',
'field' => 'authorid',
),
'mybookbookcollectionrel' => array(
'left_table' => 'mybook',
'left_field' => 'id',
'field' => 'mybookid',
),
'bookcollection' => array(
'left_table' => 'mybookbookcollectionrel',
'left_field' => 'bookcollectionid',
'field' => 'id',
),*/
);
//SONGREL
$data['mybookbookcollectionrel']['table']['group'] = t('mymodule');
// For other base tables, explain how we join
$data['mybookbookcollectionrel']['table']['join'] = array(
// author links to node directly via vid.
/*
'author' => array(
'left_field' => 'id',
'field' => 'authorid',
),
'bookcollection' => array(
'left_field' => 'id',
'field' => 'bookcollectionid',
),*/
);
// ----------------------------------------------------------------
// Fields
// authorid
$data['author']['id'] = array(
'title' => t('Author ID'), // The item it appears as on the UI,
'help' => t('The Author ID.'), // The help that appears on the UI,
// Information for displaying a title as a field
'field' => array(
'handler' => 'views_handler_field',
'click sortable' => TRUE,
'numeric' => TRUE,
),
'argument' => array(
'handler' => 'views_handler_argument_node_vid',
'click sortable' => TRUE,
'numeric' => TRUE,
),
);
//author vid
$data['author']['vid'] = array(
'title' => t('Author vid'), // The item it appears as on the UI,
'help' => t('The Author vid.'), // The help that appears on the UI,
// Information for displaying a title as a field
'field' => array(
'handler' => 'views_handler_field',
'click sortable' => TRUE,
'numeric' => TRUE,
),
'argument' => array(
'handler' => 'views_handler_argument_node_vid',
'click sortable' => TRUE,
'numeric' => TRUE,
),
'relationship' => array(
'base' => 'node',
'field' => 'vid',
'handler' => 'views_handler_relationship',
'label' => t('Author Node Relation'),
),
);
// authorname
$data['author']['name'] = array(
'title' => t('Author Name'), // The item it appears as on the UI,
'help' => t('The Author Name.'), // The help that appears on the UI,
// Information for displaying a title as a field
'field' => array(
'handler' => 'views_handler_field',
'click sortable' => TRUE,
),
'sort' => array(
'handler' => 'views_handler_sort',
),
);
// Bookcollection ID
$data['bookcollection']['id'] = array(
'title' => t('Bookcollection ID'), // The item it appears as on the UI,
'help' => t('The bookcollection id'), // The help that appears on the UI,
// Information for displaying a title as a field
'field' => array(
'handler' => 'views_handler_field',
'click sortable' => TRUE,
),
'relationship' => array(
'base' => 'mybookbookcollectionrel',
'field' => 'bookcollectionid',
'handler' => 'views_handler_relationship',
'label' => t('Bookcollection Mybook Relation'),
),
);
// Bookcollection ID
$data['bookcollection']['authorid'] = array(
'title' => t('Bookcollections Author ID'), // The item it appears as on the UI,
'help' => t('The bookcollections author id'), // The help that appears on the UI,
// Information for displaying a title as a field
'field' => array(
'handler' => 'views_handler_field',
'click sortable' => TRUE,
),
'relationship' => array(
'base' => 'author',
'field' => 'id',
'handler' => 'views_handler_relationship',
'label' => t('Bookcollection Author Relation'),
),
);
// Bookcollection: Node vid
$data['bookcollection']['vid'] = array(
'title' => t('Bookcollection vid'), // The item it appears as on the UI,
'help' => t('The bookcollection vid'), // The help that appears on the UI,
// Information for displaying a title as a field
'field' => array(
'handler' => 'views_handler_field',
'click sortable' => TRUE,
),
'argument' => array(
'handler' => 'views_handler_argument_node_vid',
'click sortable' => TRUE,
'numeric' => TRUE,
),
'relationship' => array(
'base' => 'node',
'field' => 'vid',
'handler' => 'views_handler_relationship',
'label' => t('Bookcollection Node Relationship'),
),
);
// Bookcollectionname
$data['bookcollection']['name'] = array(
'title' => t('Bookcollection Name'), // The item it appears as on the UI,
'help' => t('The bookcollection name'), // The help that appears on the UI,
// Information for displaying a title as a field
'field' => array(
'handler' => 'views_handler_field',
'click sortable' => TRUE,
),
'sort' => array(
'handler' => 'views_handler_sort',
),
);
// Mybook id
$data['mybook']['id'] = array(
'title' => t('Mybook ID'), // The item it appears as on the UI,
'help' => t('The Mybook ID.'), // The help that appears on the UI,
// Information for displaying a title as a field
'field' => array(
'handler' => 'views_handler_field',
'click sortable' => TRUE,
'numeric' => TRUE,
),
'relationship' => array(
'base' => 'mybookbookcollectionrel',
'field' => 'mybookid',
'handler' => 'views_handler_relationship',
'label' => t('Mybook Bookcollection Relation'),
),
);
// Mybook vid
$data['mybook']['vid'] = array(
'title' => t('Mybook vid'), // The item it appears as on the UI,
'help' => t('The Mybook vid.'), // The help that appears on the UI,
// Information for displaying a title as a field
'field' => array(
'handler' => 'views_handler_field',
'click sortable' => TRUE,
'numeric' => TRUE,
),
'argument' => array(
'handler' => 'handler_argument_node_vid',
'click sortable' => TRUE,
'numeric' => TRUE,
),
'relationship' => array(
'base' => 'node',
'field' => 'vid',
'handler' => 'views_handler_relationship',
'label' => t('Mybook Node Relation'),
),
);
// Mybook: AuthorId
$data['mybook']['authorid'] = array(
'title' => t('Mybooks Author ID'), // The item it appears as on the UI,
'help' => t('The Mybooks Author ID.'), // The help that appears on the UI,
// Information for displaying a title as a field
'field' => array(
'handler' => 'views_handler_field',
'click sortable' => TRUE,
'numeric' => TRUE,
),
'relationship' => array(
'base' => 'author',
'field' => 'id',
'handler' => 'views_handler_relationship',
'label' => t('Mybook Author Relation'),
),
);
// Mybook name
$data['mybook']['title'] = array(
'title' => t('Mybook Title'), // The item it appears as on the UI,
'help' => t('The mybook title'), // The help that appears on the UI,
// Information for displaying a title as a field
'field' => array(
'handler' => 'views_handler_field',
'click sortable' => TRUE,
),
'sort' => array(
'handler' => 'views_handler_sort',
),
);
// Mybookbookcollectionrel bookcollectionid
$data['mybookbookcollectionrel']['bookcollectionid'] = array(
'title' => t('Mybook Bookcollection Relation Bookcollection ID'), // The item it appears as on the UI,
'help' => t('The mybook bookcollection relation bookcollection id'), // The help that appears on the UI,
// Information for displaying a title as a field
'field' => array(
'handler' => 'views_handler_field',
'click sortable' => TRUE,
),
'relationship' => array(
'base' => 'bookcollection',
'field' => 'id',
'handler' => 'views_handler_relationship',
'label' => t('Mybook Author Relation'),
),
);
// Mybookbookcollectionrel mybookid
$data['mybookbookcollectionrel']['mybookid'] = array(
'title' => t('Mybook Bookcollection Relation Mybook ID'), // The item it appears as on the UI,
'help' => t('The mybook bookcollection relation mybook id'), // The help that appears on the UI,
// Information for displaying a title as a field
'field' => array(
'handler' => 'views_handler_field',
'click sortable' => TRUE,
),
'relationship' => array(
'base' => 'mybook',
'field' => 'id',
'handler' => 'views_handler_relationship',
'label' => t('Mybook Author Relation'),
),
);
return $data;
}
?>
Comments
Comment #1
brainski commentedDoes anyone have a hint for me?
@merlinofchaos: I know, you're extremly busy. But it seems that you are the only one, that can help me...
Comment #2
merlinofchaos commentedHere is a custom relationship handler that handles multiple table relationships that works:
This might help you.
Comment #3
brainski commentedDear merlinofchaos
After 3 days studying and testing your code, I was able to do all these relationships. It was necessary to create my own relationship handlers. But in the end it was working.
Thank you very much for your code sample! I appreciate your help!
Comment #4
merlinofchaos commentedI'm glad you got it working!
Just FYI, there's a bug in the code I pasted above:
should be:
But otherwise it's working. (You can tell from the comments that this was modified from nodequeue stuff. Yay cut & paste leftovers)
Comment #5
Anonymous (not verified) commentedAutomatically closed -- issue fixed for two weeks with no activity.
Comment #6
ruralrooster commenteddid you make a module with this? Or where to you upload this handler file? what file name?
Comment #7
leon kessler commentedQuite an old thread, but I used the code here to create a relationship handler for double joins. In case anyone needs it.
(Also, would be interested to know if this is done in the "correct" way, in particular defining the additional join data in the field definition).
in includes/yourmodule_handler_double_join_relationship.inc
Then to implement this handler for a field, in yourmodule.views.inc
So this lets you set all the fields for the double join within the definition of the field relationship.
The above example would give
JOIN second_table ON sample_table.sample_field = second_table.second_field
JOIN users ON users.uid = second_table.uid
Comment #7.0
kanani commentedadded code tags around view