I am trying to get a summed field in medoo.
My sql at the moment is like:
$database->debug()->select("user_rupees_in_house", [
"[<]rupees" => ["rupee_id" => "ID"]
], [
"name",
"amount",
"amount_spend"
], [
"user_uuid" => $user,
"GROUP" => "rupee_id"
]);
The debug logs the following statement:
SELECT `name`,`amount`,`amount_spend`, `rupee_id`
FROM `user_rupees_in_house`
RIGHT JOIN `rupees`
ON `user_rupees_in_house`.`rupee_id` = `rupees`.`ID`
WHERE `user_uuid` = '4da9ff11-56ca3a2f-b3ab-a25b9230'
GROUP BY `rupee_id`
What I'm trying to achieve is:
SELECT `name`,SUM(`amount`),SUM(`amount_spend`), `rupee_id`
FROM `user_rupees_in_house`
RIGHT JOIN `rupees`
ON `user_rupees_in_house`.`rupee_id` = `rupees`.`ID`
WHERE `user_uuid` = '4da9ff11-56ca3a2f-b3ab-a25b9230'
GROUP BY `rupee_id`
Does anybody know how to make this statement in medoo?
[EDIT 1]
Found another way of achieving this
// Get the rupee types
$rupee_types = $database->select("rupees", "ID");
foreach ($rupee_types as $rupee_type) {
$amount = $database->sum("user_rupees_in_house", "amount", [
"AND" => [
"rupee_id" => $rupee_type,
"user_uuid" => $user
]
]);
// Build array of rupees
}
This will make a lot more calls to the database, but is working just fine as long as the SELECT statement does not support aggregate functions.
Medoo doesn't support aggregate function in SELECT statement. Use raw query instead.
Try this:
$result = $database->query(
"SELECT `name`,SUM(`amount`),SUM(`amount_spend`), `rupee_id`
FROM `user_rupees_in_house`
RIGHT JOIN `rupees`
ON `user_rupees_in_house`.`rupee_id` = `rupees`.`ID`
WHERE `user_uuid` = '$user'
GROUP BY `rupee_id`"
)->fetchAll();
Reference
Related
I want to do a search of data and get the number of entries it has on another table
$query = $this->find();
$query->select([
'name',
'code',
'count' => "(
SELECT
COUNT(products_branches.id)
FROM
products_branches
INNER JOIN
branches
ON branches.company_id = products_branches.company_id
AND branches.code = products_branches.branch_code
WHERE
products_branches.deleted = 0
AND products_branches.carried = 1
AND products_branches.company_id = $company_id
AND products_branches.branch_code = code
)",
]);
is there a way that I could use the code fetch in the select and use at as one of the condition in the search condition of the subquery?
I want to search the number of entries each name and code has on product_branches table
What you're looking to do is possible, but you've got a few more steps to complete. You need to make sure you create an Association between the products_branches and branches table first. Then you can use the where() function to do what you want to do. Something like this:
$q = $this-find('all')
->select(['Branches.name', 'Branches.code'])
->contain(['ProductsBranches'])
->where(['ProductsBranches.deleted' => 0,
'ProductsBranches.carried' => 1,
'ProductsBranches.company_id' => $company_id,
'ProductsBranches.branch_code' => $code]);
$count = $q->all()->count();
I need to implode an array into a string that looks like this.
"2","3"
That I can place inside my query
select * from example
where id IN ()
I've imploded the array and it gives me the string
`"2,3" `
which doesn't work. Any help would be appreciated.
Here's my query with query builder
$package_id = [
0 => 2,
1 => 3
];
$query = "SELECT
MIN(`prices`.`amount`) as `low_price`,
MAX(`prices`.`amount`) as `high_price`,
`packages`.`id` as `package_id`,
`packages`.`order` as `package_order`,
`packages`.`label` as `package_name`,
`packages`.`description` as `package_description`,
`packages`.`interval` as `package_interval`
from `packages`
inner join `prices` on `prices`.`package_id` = `packages`.`id`
where `packages`.`id` IN (:chosen_package_id)
group by `package_id`
order by `packages`.`id` asc
";
$prices = DB::select($query, [
'chosen_package_id' => $package_id,
]);
I am using DB facade and select method to run raw SQL queries with bindings. Just need to know can we do have multiple parameters with the same name in the query and replace that by providing only 1 binding with parameter name.
e.g.
$sql = "SELECT students.id, students.name FROM students
where students.student_id = :student_id
where added_on = ( SELECT MAX( added_on ) AS newdate
FROM students WHERE student_id = :student_id)"
return DB::select($sql, [
'student_id' => 1
]);
note: it might possible that I do not have to use student_id twice in this query. It just an example.
The purpose is to know if we can achieve this.
I don't believe its possible, it's not ideal, but I generally do something like:
$sql = "SELECT students.id, students.name FROM students
where students.student_id = :student_id_1
where added_on = ( SELECT MAX( added_on ) AS newdate
FROM students WHERE student_id = :student_id_2)"
$student_id = 1;
return DB::select($sql, [
'student_id_1' => $student_id,
'student_id_2' => $student_id
]);
How would I make the $query_ppimage results a sub array from the first users query? At the moment, the output is outputting a user, then a profile image, under the user, rather than inside the users array. Therefore they aren't linked.
How would I do such a thing?
Here is my code:
$query_user = "SELECT *,'user' AS type FROM users WHERE username LIKE '".$query."' OR firstname LIKE '".$query."' OR lastname LIKE '".$query."'";
$quser = $conn->query($query_user);
$rows = array();
while($user = mysqli_fetch_assoc($quser)) {
$query_ppimage = "SELECT id, post_id, relation, userID, file_format FROM media WHERE userID = '".$user['id']."' AND relation = 'profile_picture' UNION ALL SELECT -1 id, '55529055162cf' post_id, 'profile_picture' relation, '0' userID, 'jpg' file_format ORDER BY id DESC";
$qppimg = $conn->query($query_ppimage);
while($ppimg = mysqli_fetch_assoc($qppimg)) {
$rows[] = $ppimg;
$rows[] = $user;
}
}
Here is how the array is returned:
[
{
"id": "117",
"post_id": "1",
"relation": "profile_picture",
"userID": "3",
"file_format": "jpg"
},
{
"id": "3",
"email": "casper#socialnetwk.com",
"type": "user"
},
]
How it should look, or something similar. I don't think I named the sub array correctly, but it needs a name ppimage
[
{
"id": "3",
"email": "casper#socialnetwk.com",
"type": "user"
ppimage: {
"id": "117",
"post_id": "1",
"relation": "profile_picture",
"userID": "3",
"file_format": "jpg"
}
},
]
You are adding to $rows twice and appending two separate elements. Try building your array element first and then adding it into the $rows array. Something like this:
$newrow = $user;
$newrow['ppimage'] = $ppimg;
$rows[] = $newrow;
Using JOIN, you could limit this to one single query. Having a query inside a loop is never a good idea, and you should avoid it if you can. Furthermore, you should use prepared statements in order to protect against SQL injection.
The code below uses a JOIN, so that you just get one query - and structures the array as shown in the example. This is hard-coded, as its easier to control what goes where, since we now use a JOIN, the data is all fetched at once (and not in separate variables).
$row = array();
$stmt = $conn->prepare("SELECT m.id, m.post_id, m.relation, m.file_format, u.id, u.email, 'user' as type
FROM media m
JOIN users u ON u.id=m.userID
WHERE m.relation = 'profile_picture'
AND (username LIKE ?
OR firstname LIKE ?
OR lastname LIKE ?)
ORDER BY m.id DESC");
$stmt->bind_param("sss", $query, $query, $query);
$stmt->execute();
$stmt->bind_result($mediaID, $postID, $relation, $file_format, $userID, $user_email, $type);
while ($stmt->fetch()) { // If you just expect one row, use LIMIT in the query, and remove the loop here
$row[] = array('id' => $userID,
'email' => $user_email,
'type' => $type,
'ppimage' => array('id' => $mediaID,
'post_id' => $postID,
'relation' => $relation,
'userID' => $userID,
'file_format' => $file_format)
);
}
$stmt->close();
How can I prevent SQL injection in PHP?
MySQL JOIN
Using Zend DB. I am trying to figure out how to write this query using the DB Class.
select
org.orgid
org.role
user.userid
user.firstname
from orgTable org
join userTable user on org.userid = user.userid
where org.orgid = 'generated-id'
from the documents I understand or think I understand how to do it with one definition using an AS like condition, but even then Im still not sure. Eventually this will branch out into a multi table join, based on cross table conditions so not sure how to achieve this to begin with.
I think this is what are you looking for
$db = Zend_Db::factory( ...options... );
$select = $db->select()
->from(array('org' => 'orgTable'),
array(
'orgid' => 'org.orgid',
'role' =>'org.role',
'userid' =>'user.userid',
'firstname' =>'user.firstname'
))
->join(array('user' => 'userTable'),
'org.userid = user.userid',array())
->where('org.orgid = ?',$generated_id);
Here is a Zend_Db_Select that returns the result you are looking for.
$select = $db->select()
->from(array('org' => 'orgTable'), array('orgid', 'role'))
->join(array('user' => 'userTable'), 'org.userid = user.userid', array('userid', 'firstname'))
->where('org.orgid = ?', 'generated-id');
You can use the array notation for table names to get the aliased names in the query.
Hope that helps.
In zend framework 2 , the following code helps you what are you looking for
$generated_id = 1 ;
$select = new \Zend\Db\Sql\Select( array('org' =>'orgTable'));
$select->columns(array('orgid','role') )
->join( array('user' => 'userTable'),
'org.userid = user.userid',
array('userid','firstname')
)->where( array('org.orgid' => $generated_id ) );
if your adapter platform is mysql, then for printing sql
$mysqlPlatform = new \Zend\Db\Adapter\Platform\Mysql();
echo $select->getSqlString( $mysqlPlatform );
which print sql as
SELECT
`org`.`orgid` AS `orgid`,
`org`.`role` AS `role`,
`user`.`userid` AS `userid`,
`user`.`firstname` AS `firstname`
FROM
`orgTable` AS `org`
INNER JOIN `userTable` AS `user`
ON `org`.`userid` = `user`.`userid`
WHERE
`org`.`orgid` = '1'