Write custom SQL Query in DataObject::get() - php

I am using Silverstripe version 2.4 . I did not update to new version because I have made many changes and now it is impossible for me to migrate to newer version.
I have a custom SQL query and I want the query to run in DataObject::get();
Here is my Query
SELECT STL.* FROM Page P join SiteTree_Live STL on P.ID = STL.ID join Site S on P.SiteID = S.ID where S.ID = 60 and STL.ShowInMenus = 1 and STL.ParentID = 0 and STL.CanViewType <> 'NotLoggedInUsers' ..
How can I write this query in DataObject::get();
Any help would be greatly appreciated.. Thanks

the easiest way is using the ORM to build that query, in 2.4 it could be done like this (only works if class Site has a has_many to Page, which I assume is the case here):
$site = DataObject::get('Site', 'ID = 60');
// the line below assumes that the has_many in site is called "Pages"
$pages = $site->Pages("ShowInMenus = 1 AND ParentID = 0 AND CanViewType <> 'NotLoggedInUsers'");
alternatively, if you want to save yourself that extra query for Site, you can do it with 1 DataObject::get() using the join parameter. should look something like this:
$pages = DataObject::get(
'Page',
"Site.ID = 60 AND ShowInMenus = 1 AND ParentID = 0 AND CanViewType <> 'NotLoggedInUsers'",
null,
'LEFT JOIN Site ON Site.ID = Page.SiteID'
);

Related

How can I order the results of an SQL query by the count of another table based on a shard ID?

I have an SQL query that fetches posts from a database. Everything works fine, but now I need to order the results by the number of comments each post has. The comments are on a separate table and they have a post_id column that links it to the post. I need to order the posts by the count of the comments table based on a shard ID? I have tried everything but every time I try to add something to my query it stops running completely and leaves my page blank. I need help to know where to put the other JOIN statement. This is my query:
$union = "UNION ALL
(
SELECT DISTINCT wallposts.p_id,wallposts.is_profile_notes,wallposts.times_viewed,wallposts.columnTimesShared,
wallposts.marked,wallposts.secure_id,wallposts.reshared,wallposts.group_id,
wallposts.totaluploads,wallposts.WallUploadID,wallposts.type,
wallposts.value,wallposts.media,wallposts.youtube,wallposts.post_type,
wallposts.privacy,wallposts.tagedpersons,wallposts.with_friends_tagged,wallposts.emotion_head,wallposts.selected_emotion,wallposts.title,
wallposts.url,wallposts.description,wallposts.cur_image,
wallposts.uip,wallposts.likes,wallposts.userid,
wallposts.posted_by,wallposts.post as postdata,wallusers.*,
UNIX_TIMESTAMP() - wallposts.date_created AS TimeSpent,
PosterTable.mem_pic as posterPic, PosterTable.gender as posterGender,PosterTable.oauth_uid as poster_oauth_uid, PosterTable.username as posterUsername,
PosterTable.mem_fname as posterFname,PosterTable.work as posterWork,
PosterTable.mem_lname as posterLname,walllikes_track.id as PostLikeFound,wallposts.date_created
FROM
wallusers,wallusers as PosterTable, wallposts
LEFT JOIN walllikes_track
ON wallposts.p_id = walllikes_track.post_id AND walllikes_track.member_id = ".$user_id."
WHERE
wallusers.active = 1
AND
PosterTable.active = 1
AND
wallposts.group_id IN (".$groups.")
AND
wallposts.group_id != 0
AND
PosterTable.mem_id = wallposts.posted_by
AND
wallposts.marked < ".$this->flagNumber."
AND
wallusers.mem_id = wallposts.posted_by ) ";
The comments table is called wallcomments and it has a column called post_id. I know I need to use JOIN and COUNT but I don't know where to put it within my current code.
Try this query, I didn't run but i updated it.
SELECT wallposts.p_id,wallposts.is_profile_notes,wallposts.times_viewed,wallposts.columnTimesShared,
wallposts.marked,wallposts.secure_id,wallposts.reshared,wallposts.group_id,
wallposts.totaluploads,wallposts.WallUploadID,wallposts.type,
wallposts.value,wallposts.media,wallposts.youtube,wallposts.post_type,
wallposts.privacy,wallposts.tagedpersons,wallposts.with_friends_tagged,wallposts.emotion_head,wallposts.selected_emotion,wallposts.title,
wallposts.url,wallposts.description,wallposts.cur_image,
wallposts.uip,wallposts.likes,wallposts.userid,
wallposts.posted_by,wallposts.post as postdata,wallusers.*,
UNIX_TIMESTAMP() - wallposts.date_created AS TimeSpent,
PosterTable.mem_pic as posterPic, PosterTable.gender as posterGender,PosterTable.oauth_uid as poster_oauth_uid, PosterTable.username as posterUsername,
PosterTable.mem_fname as posterFname,PosterTable.work as posterWork,
PosterTable.mem_lname as posterLname,walllikes_track.id as PostLikeFound,wallposts.date_created
FROM
wallusers,wallusers as PosterTable, wallposts
WHERE
wallusers.active = 1
AND
PosterTable.active = 1
AND
wallposts.group_id IN (".$groups.")
AND
wallposts.group_id != 0
AND
PosterTable.mem_id = wallposts.posted_by
AND
wallposts.marked < ".$this->flagNumber."
AND
wallusers.mem_id = wallposts.posted_by ) " AND wallposts.p_id = walllikes_track.post_id AND walllikes_track.member_id = ".$user_id.";
A more readable query might look like this...
At least then we'd have a chance.
SELECT DISTINCT p.p_id
, p.is_profile_notes
, p.times_viewed
, p.columnTimesShared
, p.marked
, p.secure_id
, p.media...
FROM wallposts p...

Select multiple columns from inner join in Silverstripe 3.1

In my events calendar module for Silverstripe 3.1, i have added some additional fields to CalendarEvent. I want to make use of these in my template, but from my researches i have seen that events are exported as being CalendarDateTime so i can't use my additional fields.
I have found that in getStandardEvents function, there is a inner join which i think is causing the problem, but i can't figure it out to join the columns from CalendarEvent
$list = DataList::create('CalendarDateTime')
->filter(array(
'EventID' => [139, 140, 141, 143]
))
->innerJoin('CalendarEvent', "EventID = \"{CalendarEvent}\".\"ID\"")
->innerJoin("SiteTree", "\"SiteTree\".\"ID\" = \"{CalendarEvent}\".\"ID\"")
->where("Recursion != 1");
Note: In my code, i have some of the columns as variables, so i have written them as the values that are reffering to.
Here is the original code:
$list = DataList::create($datetimeClass)
->filter(array(
$relation => $ids
))
->innerJoin($eventClass, "$relation = \"{$eventClass}\".\"ID\"")
->innerJoin("SiteTree", "\"SiteTree\".\"ID\" = \"{$eventClass}\".\"ID\"")
->where("Recursion != 1");
I have tried to add the 'CalendarEvent' as a second parameter inside DataList::create(), but no result. I have the same output.
So how can i select columns from CalendarDateTime and CalendarEvent tables ?
Any help would be appreciated.Thanks
I have found a manual way:
$list = DB::query('SELECT * FROM "CalendarDateTime" INNER JOIN "CalendarEvent" ON "EventID" = "CalendarEvent"."ID" INNER JOIN "SiteTree" ON "SiteTree"."ID" = "CalendarEvent"."ID" WHERE "Recursion" != 1');
Any other solutions are welcome.

codeigniter, Using Case When for Where Query

I have this query which i want to make it work in codeigniter query form, so want to know if its possible or not.
This is the query i want to implement in Codeigniter in codeigniter's own way.
use zorkif_next;
SELECT
`osp_job_status_track`.`StatusID`,
`osp_job_status_track`.`SubStatusID`,
`osp_job_sub_status`.`CurrentStatus`
FROM
(`osp_job_details`)
LEFT JOIN
`osp_job_status_track` ON `osp_job_status_track`.`JobID` = `osp_job_details`.`JobID`
LEFT JOIN
`osp_job_status` ON `osp_job_status`.`StatusID` = `osp_job_status_track`.`StatusID`
LEFT JOIN
`osp_job_sub_status` ON `osp_job_sub_status`.`SubStatusID` = `osp_job_status_track`.`SubStatusID`
LEFT JOIN
`hr_employee_details` ON `hr_employee_details`.`EmployeeID` = `osp_job_details`.`AssignToEmployeeID`
LEFT JOIN
`osp_job_type` ON `osp_job_type`.`JobTypeID` = `osp_job_details`.`JobtypeID`
WHERE
-- `isDefault` = 1
-- AND
CASE WHEN `osp_job_status`.`StatusID` = 2
THEN `osp_job_sub_status`.`CurrentStatus` = 3
ELSE `osp_job_status`.`StatusID` >= 2
END ;
So how to implement this query in
$this->db->where($where);
???
It is not possible in CI.You need to write your own query. Please have a look on this file.You can see all the available methods there.
\system\database\DB_active_rec.php

Only use AND statment when if is true in mysql query

I have updated an old system and I have a query problem.
To get to business this is the direct problem:
There are new records witch are associated with an id to other records. There are also old records which are not.
Case1 : there is a INT id and when that is present the query has to use AND after an include.
Case 2 : when the value of the INT id is 0 it has to do nothing
This is the part of the query where I need to make an variable AND statement:
LEFT JOIN table v ON v.producten_id = i.producten_id AND v.t5_id = i.t5_id AND i.id = v.inkoop_id
I never used IF stamens inside a query but i am looking for something like this:
LEFT JOIN table v ON v.producten_id = i.producten_id AND v.t5_id = i.t5_id if(v.inkoop_id > 0){AND i.id = v.inkoop_id}
Try this:
LEFT JOIN table v
ON v.producten_id = i.producten_id
AND v.t5_id = i.t5_id
AND (v.inkoop_id <= 0 OR i.id = v.inkoop_id)
How about this....
LEFT JOIN table v ON v.producten_id = i.producten_id
AND v.t5_id = i.t5_id
AND ((v.inkoop_id > 0 AND i.id = v.inkoop_id) OR (v.inkoop_id = 0))

Joining Tables With Zend Framework PHP

I am relatively new to the Zend Framework.
I understand the usage of Zend_Table and can obtain data using the Zend functions from the table associated with that class.
For example I have a video table and in another table I have the association between the video and what category it is in.
Im a little stumped how to active a select like the following within the framework:
SELECT * FROM video,category WHERE category.category_id = 3 AND video.id = category.video_id
Any advice would be great.
Thanks.
$db->select()->from('video')->joinInner('category','video.id = category.video_id')->where('category.category_id = ?',3)
BTW: It looks like you have wrong db design. You should have category_id in your video table (if 1 video -> 1 category) or have a connection table (M:N), but it seems wrong to have video id stored in category.
I would use Zend_Db_Select:
$select = $this->db->select()->from(array('v' => 'video'))
->join(array('c' => 'category'),'v.id = c.video_id')
->where('c.category_id = ?', 3);
print_r($select->__toString());
Output:
SELECT `v`.*, `c`.* FROM `video` AS `v` INNER JOIN `category` AS `c` ON v.id = c.video_id WHERE (c.category_id = 3)

Categories