How to use multiple on clause in joining in zend framework 2 - zend-framework2

I am doing like this sql into zend framework sql pattern.
SELECT
jobs . *,
c.id AS cid,
c.name AS name,
c.companyImage AS companyImage,
c.logo AS logo,
count(app.userId) AS t_app,
app.applyStatus AS applyStatus,
app.userId AS appUserId
FROM
jobs
LEFT JOIN
companies AS c ON jobs.companyName = c.id
LEFT JOIN
applicants AS app ON jobs.id = app.jobId AND app.applyStatus = 1
WHERE
jobs.ownerId = 16 AND jobs.draftId != 0
GROUP BY jobs.id
ORDER BY jobs.id DESC
LIMIT 3
For this sql I already write this code for zend framework 2
$adapter = $this->tableGateway->getAdapter();
$sql = new Sql($adapter);
$select = $sql->select();
$select->from('jobs')
->join(array('c' => 'companies'), 'jobs.companyName = c.id', array('cid' => 'id', 'name', 'companyImage', 'logo'), 'left')
->join(array('app' => 'applicants'), ' jobs.id = app.jobId AND app.applyStatus = 1', array('t_app' => new Expression('count(app.userId)'), 'applyStatus', 'appUserId' => 'userId'), 'left')
->where("jobs.ownerId ={$userId} AND jobs.draftId != 0")
->group('jobs.id')
->order('jobs.id DESC')
->limit(3);
$statement = $sql->getSqlStringForSqlObject($select);
$results = $adapter->query($statement, $adapter::QUERY_MODE_EXECUTE);
but does not work properly and its give a message like below.
SQLSTATE[42S22]: Column not found: 1054 Unknown column '1' in 'on clause'

The issue is this part:
app.applyStatus = 1
The framework is escaping 1 as if it were a column name, 1.
You need to enclose this part in an Expression too
new Expression('jobs.id = app.jobId AND app.applyStatus = 1')
I think the use of Expressions in the 'ON' parameter of the join method may depend on the version of ZF2 you are using, I think it was added 2.1+

Building on this answer. If you also want your table & column identifiers to be escaped, use this syntax:
use Zend\Db\Sql\Expression;
...
$onExpression = new Expression('? = ? AND ? = ?',
['jobs.id', 'app.jobId', 'app.applyStatus', 1],
[Expression::TYPE_IDENTIFIER, Expression::TYPE_IDENTIFIER,
Expression::TYPE_IDENTIFIER, Expression::TYPE_LITERAL]
);
$select->from('jobs')
->join(array('app' => 'applicants'), $onExpression, array('t_app' => new Expression('count(app.userId)'), 'applyStatus', 'appUserId' => 'userId'), 'left');
The Expression constructor accepts the string, then arguments, then argument types.
public function __construct($expression = '', $parameters = null, array $types = [])

This will create a security issue. Zf2 changes your query to this:
Select * from tableA inner join tableB
on `tableA`.`column` = `tableB`.`column`
AND `tableB`.`column` = `1`
It adds
`
to each part for security issues! By using new Expression you are bypassing it and if you get applyStatus from user entry, get sure about its filtering!

Related

select joins and group by in codeigniter

In Codeigniter3, I have the following select join model:
public function get_post()
{
$q = $this->db->select('posts.id, posts.active, posts.title, posts.close_date, users.name')
->from('posts')
->join('users', 'posts.user_id = users.id', 'left')
->where('posts.active','1')
->where(['posts.active' => '1', 'posts.close_date >=' => date('Y-m-d')])
->order_by('posts.updated_at', 'DESC')->get();
return $q;
}
How can I list all posts with count posts for each user (count only posts where posts.active = 1 and posts.close_date >= current date)?
If CI can't do the job, please give me the sql query.
Here you go:
With complex queries like this, the best way is to store the sql script in a string variable and use $this->db->query() to execute it.
This query is in MySQL:
public function get_posts() {
$sql = "
SELECT `posts`.`id`, `posts`.`active`, `posts`.`title`, `posts`.`close_date`, users.name, COUNT(`posts`.`user_id`) AS `active_post_count`
FROM `posts`
LEFT JOIN `users` ON `posts`.`user_id` = `users`.`id`
WHERE `posts`.`active` = ?
AND `posts.close_date` >= ?
ORDER BY `posts`.`updated_at` DESC;
";
$now = new DateTime('now');
$binds = [1, $now->format('Y-m-d H:i:s')];
return $this->db->query($sql, $binds)->result_array();
}
Here's a sample code on how to access the post count:
$this->Your_model->get_posts()[0]['active_post_count'];
See CodeIgniter's docs on Generating Query Results:
If you want the result as an object instead, use result_object() over result_array().

How to get value from custom profile field in moodle in code?

How to get value from custom profile field in moodle?
i want to include the profile field in user.php
If you want to load all the user profile fields, then you can start with a user object
$user = $DB->get_record('user', array('id' => $userid));
and then call
profile_load_custom_fields($user);
to fill in the $user->profile with an array of all the custom fields.
Alternatively, you can get the contents of a single profile field via:
$sql = "SELECT ud.data
FROM {user_info_data} ud
JOIN {user_info_field} uf ON uf.id = ud.fieldid
WHERE ud.userid = :userid AND uf.shortname = :fieldname";
$params = array('userid' => $userid, 'fieldname' => 'NameOfCustomField');
$fieldvalue = $DB->get_field_sql($sql, $params);
Note this code is written off the top of my head and untested, so it may have some typos in it.
You can use:
$Data = $USER->profile['YourCustomField'];
I finally made it!!!
$sql = 'SELECT DISTINCT u.id AS userid, u.username, uif.shortname, uid.data FROM prefix_user u JOIN prefix_user_info_data as uid on uid.userid = u.id JOIN prefix_user_info_field as uif on uid.fieldid = uif.id JOIN prefix_user_enrolments ue ON ue.userid = u.id JOIN prefix_enrol e
ON e.id = ue.enrolid JOIN prefix_role_assignments ra ON ra.userid = u.id JOIN prefix_context ct ON ct.id = ra.contextid AND
ct.contextlevel = 50 JOIN prefix_course c ON c.id = ct.instanceid AND e.courseid = c.id JOIN prefix_role r ON r.id = ra.roleid
where uif.shortname = \'fieldname\' and u.id ='.$userid;
$records = $DB->get_recordset_sql($sql, array(), $params=null, $limitfrom=0, $limitnum=0);
foreach($records as $record){
$user['fieldname'] = $record->data;
}
custom fields are stored in 'user_info_field' table and data for each field and user are stored in 'user_info_data' table then you should know your fieldid in database and select data based on this id:
$field = $DB->get_record('user_info_field', array('shortname' => 'customfieldshortname'));
$fieldvalues = $DB->get_records('user_info_data',array('fieldid' => $field->id));
i hope my solutions help anybody:
need this lib
require_once($CFG->dirroot.'/user/profile/lib.php');
and now you can use:
profile_load_data($USER);
$USER->profile_field_%your_field_name%
example $USER->profile_field_HaveAnotherGradeBook;

how to convert sql query in ruby and rails?

SELECT A.FirstName, A.LastName, B.PatientId, B.RoomNumber, B.AdmissionDate, B.DischargeDate, B.MeasureCategory
FROM DimPatient A, DimPatientStay B
WHERE A.Id = B.PatientId AND A.FirstName = 'Anuj' AND B.MeasureCategory = 'ED'
hi some updation for this
i solved this prob by
MODELNAME.find_by_sql("your sql query")
You can try this to find the result from sql query in Rails
query_params = Hash.new
sql_query = "SELECT A.FirstName, A.LastName, B.PatientId, B.RoomNumber, B.AdmissionDate, B.DischargeDate, B.MeasureCategory
FROM DimPatient A, DimPatientStay B
WHERE A.Id = B.PatientId AND A.FirstName = :first_name AND B.MeasureCategory = :measure_category"
query_params[:first_name] = first_name
query_params[:measure_category] = measure_category
#query_results = ActiveRecord::Base.connection.select_all(
ActiveRecord::Base.send("sanitize_sql_array",[sql_query, query_params] )
)
I guess you could try:
ActiveRecord::Base.connection().execute(#your_sql_here)
Suppose A is one class and B is another, you should use includes as following:
A.includes(:b).where(...) # add you condition in where
I suggest to check good video tutorials of ActiveRecord here

Rails Nested Query

I have follow query
notes = Note.where('notes.id IN
(
SELECT "notes"."id" FROM "notes"
WHERE "notes"."circle_id" = ?
)
OR notes.id IN
(
SELECT "notes"."id" FROM "notes"
INNER JOIN "circles_dreams"
ON "circles_dreams"."dream_id" = "notes"."dream_id"
WHERE "circles_dreams"."circle_id" = ?
)', #circle.id, #circle.id)
How to simplify this query?
Thanks.
First of all you can collect all needed notes id.
I supposed to think what you already have relations between Note and CirclesDream
note_ids = Note.where(circle_id: #circle.id).pluck(:id) # your first SELECT
dream_ids = CirclesDream.where(id: #circle.id).pluck(:note_id) # your second SELECT
notes_ids = note_ids | dreams_ids # combine them
notes = Note.where(id: notes_ids) # Now your
upd: I've just fixed typo. Changed id to note_id in second request
Try this
note_ids = Note.where('circle_id = ?', #circle.id).pluck(:id)
dream_note_ids = Note.joins(:circle_dreams).where('circle_dreams.circle_id = ?', #circle.id).plunk(:note_id)
notes_ids = note_ids | dream_note_ids
If your circle_dreams table can contain records having note_id = null, then you have to apply join. So i think this will work in your case....

sql distinct statement and use of more than one table on rails

How would you write this line in the "rails way"?
unique_attendees = CourseSessionsUser.count_by_sql(["SELECT count(DISTINCT csu.user_id) AS count_user_id FROM course_sessions_users csu, course_sessions cs WHERE cs.course_id = ? AND csu.course_session_id = cs.id"], #course.id)
The query itself is:
SELECT count(DISTINCT csu.user_id) AS count_user_id
FROM course_sessions_users csu,
course_sessions cs
WHERE cs.course_id = ?
AND csu.course_session_id = cs.id
Use count method of the rails
count = CourseSessionsUser.count('csu.user_id',
:distinct => true, :conditions => ["cs.course_id = ?", #course.id]
:joins => "cs LEFT JOIN course_sessions_users csu ON cs.id = csu.course_session_id")
This will return directly non zero integer if condition matches otherwise return zero

Resources