I have a select query in Mysql table to fetch related table with a duplicate values in a specific column(date).This will successfully display columns and its foreign keys if it has duplicate values in a column.Example two rows same value of (2014-11-10) in a date column
mysql>select man_id,date_created,count(date_created) as count
from collections
group by man_id,date_created
having count(date_created) > 1;
I want this query to convert to Doctrine query since I am using symfony 1.4 as a framework
public function getDuplicateDatePayment() {
$q = $this->createQuery()
->select('man_id','date_created','count(date_created) as count')
->from('Collections')
->groupBy('man_id','date_created')
->having('COUNT(c.date_created) > 1');
return $q->execute();
}
SELECT c.id AS c__id, c.man_id AS c__man_id FROM collections c GROUP BY c.man_id HAVING count(c.date_created) > 1 //result 1 row
why does doctrine query does not display results as expected?How to convert said doctrine query so that it will display result similar to SQL?
//result 1141 rows
update
Collections table is related to Man table in a one to many relationship.Do i have to use innerJoin for this?
After two days of trying,searching for an answer, I finally found a solution to my problem.
SELECT c.id AS c__id, c.man_id AS c__man_id FROM collections c GROUP BY c.man_id HAVING count(c.date_created) > 1
The problem of above sql result from doctrine is ,it does not include 'c.loan_id' in groupBy clause,even though I include it in groupBy clause.The solution is ,just add a separated addGroupBy clause ..And now its working.cheers..
public function getDuplicateDatePayment() {
$q = $this->createQuery()
->select('c.man_id','c.date_created','count(c.date_created) as count')
->from('Collections')
->groupBy('c.man_id')
->addGroupBy('c.date_created')
->having('count(c.date_created) > 1');
return $q->execute();
}
Related
I am trying to fetch data from 2 tables with a join query. Here I have 2 columns in 2 tables with same column name.
This is my query:
public function get_all_expenses()
{
$this->db->select("*",'category.name as cat_name');
$this->db->from('expense');
$this->db->join('category','expense.cat_id = category.id');
$this->db->join('users','expense.user_id = users.id');
$query = $this->db->get();
return $query;
}
I can fetch data of 1 column of 1 table. But I can't fetch data of another column of another table. I am using CodeIgniter.
According to the CodeIgniter documentation the database select method accept a single argument. The correct syntax for the select is then:
$this->db->select('*, category.name as cat_name');
I want to retrieve whole records from table and also the sum records from it but the problem is when i use mysql sum() function in it its only return a single record and when i remove mysql sum() function it returns the whole records the problem is with sum i google it but couldnt find releative material agains .
I am using codeigniter active records for retrieval of data please point me out where i am making mistak.ty
Here is the my model function.
function get_soorh_jama($start_date,$end_date)
{
$where=array('pe.pur_inv_date >='=>$this->date);
//$this->db->select_sum('si.chungi');
$this->db->select('pe.*,px.*,kt.name');
$this->db->from('purchase_invoice as pe');
$this->db->join('khata as kt','pe.supplier_id=kt.id');
$this->db->join('purexpenses as px','pe.pur_inv_id=px.inv_id');
$this->db->select_sum('pe.nags','sold_nags');
$this->db->where($where);
$query=$this->db->get();
echo $this->db->last_query();
return $query->result();
}
Here whats the normal query looks like.
SELECT `pe`.*, `px`.*, `kt`.`name`, SUM(`pe`.`nags`) AS sold_nags FROM (`purchase_invoice` as pe) JOIN `khata` as kt ON `pe`.`supplier_id`=`kt`.`id` JOIN `purexpenses` as px ON `pe`.`pur_inv_id`=`px`.`inv_id` WHERE `pe`.`pur_inv_date` >= '10/26/2015'
use group by pur_inv_id
SELECT `pe`.*, `px`.*, `kt`.`name`, SUM(`pe`.`nags`) AS sold_nags
FROM (`purchase_invoice` as pe) JOIN `khata` as kt
ON `pe`.`supplier_id`=`kt`.`id` JOIN `purexpenses` as px
ON `pe`.`pur_inv_id`=`px`.`inv_id` WHERE `pe`.`pur_inv_date` >= '10/26/2015'
group by pur_inv_id
My following query not return row when COUNT(*) result return 0 row
SELECT COUNT(id) test,
UNIX_TIMESTAMP(my_time)*1000 d
FROM chat_table
WHERE dept_id = 5
AND my_time >="2015-03-30"
GROUP BY DAY(my_time)
ORDER BY d ASC;
I need GROUP BY day even return 0 row. How can left join in same table? or any idea?
You can only have groups based on values that exist. If a value, for example, timestamp '2015-04-01 12:00:00' does not exist in your table, it cannot be part of the result.
You can work around this by:
handling the results of the query in a programming language, supplementing count 0 for all rows that are missing
OR creating a reference table that contains all timestamps
OR manually injecting all timestamps using a subquery and union.
The best option is the first: keep your query as it is, but write logic in the program that starts the query to automatically assume that the count is zero if the timestamp is not in the result set.
For example, in PHP:
$countsPerTimestamp = array();
foreach ($stmt->fetchAll() as $row) {
$countsPerTimestamp[$row['d']] = $row['test'];
}
$searchTimestamp = '2015-04-05 12:13:14';
if (isset($countsPerTimestamp[$searchTimestamp])) {
echo 'Count for now is: ' . $countsPerTimestamp[$searchTimestamp];
}
else {
echo 'Count for now is: 0';
}
If your table has data on every day but the where clause is filtering it out, then the easiest solution is to use conditional aggregation:
SELECT SUM(dept_id = 5) as test,
UNIX_TIMESTAMP(my_time)*1000 as d
FROM chat_table
WHERE my_time >= '2015-03-30'
GROUP BY DAY(my_time)
ORDER BY d ASC;
If those conditions are not true, then you need to start with a list of all the dates and use left join.
is it possible to get the columns names resulting by a query?
So (for example) if I have this query:
SELECT Id AS IdNumber,
(SELECT COUNT(*) FROM tab2 WHERE IdRif = T1.Id) AS TotCount
FROM tab1 T1
I'd like to get:
IdNumber
TotCount
I saw MySQL query to get column names? (and also other questions) but I wasn't able to use it for what I need.
If your query returns results just use the object(fetch_object) / array (fetch_assoc) from the row and use array_keys($row)
if no rows are returned use http://php.net/manual/en/mysqli-result.fetch-field-direct.php
$result = $db->query($sql);
$i = 0;
while ($i < $db->field_count) {
$info = $result->fetch_field_direct($i++);
echo $info->name;
}
as an example
You can fetch the query result into an Associative Array using mysql_fetch_array($result,MYSQL_ASSOC) or $result->fetch_array(MYSQLI_ASSOC) or whatever method you are using, so that the Key=>Value pair of your Associative Array would be your ColumnName=>ColumnValue.
So, irrespective of whether you are using mysql or mysqli, you would be using the same logic to get the column names.
TL;DR
Can you limit an Eloquent ORM query like using take() and skip() so that the resulting mysql query is also limited, and it doesn't have to return the entire dataset?
If so, how would you modify:
$test = User::find(1)->games->toArray();
To include limit 3 offset 2?
Tables:
users games userGames
-- id -- id -- user_id
-- name -- name -- game_id
-- steam_id
Models:
class User extends Eloquent {
public function games() {
return $this->belongsToMany('Game', 'userGames', 'user_id', 'game_id');
}
}
class Game extends Eloquent {
public function users() {
return $this->belongsToMany('User', 'userGames', 'user_id', 'game_id');
}
}
Limit in Query Builder
Using the regular Laravel Query Builder I can get all games that belong to user of id 1, and limit the result with take() and skip():
$test = DB::table('games')
->join('userGames', 'userGames.game_id', '=', 'games.id')
->where('userGames.user_id', '=', '1')->take(3)->skip(2)->get();
By listening to the illuminate.query event I can see that the query generated by this is:
select * from `games`
inner join `userGames`
on `userGames`.`game_id` = `games`.`id`
where `userGames`.`user_id` = ?
limit 3 offset 2
Limit in Eloquent ORM
When I try to recreate the same query with Eloquent:
$test = User::find(1)->games->take(2)->toArray();
I'm able to use take but adding skip causes an error. Also the resulting query does not actually contain the limit:
select `games`.*, `userGames`.`user_id` as `pivot_user_id`,
`userGames`.`game_id` as `pivot_game_id` from `games`
inner join `userGames`
on `games`.`id` = `userGames`.`game_id`
where `userGames`.`user_id` = ?
So it seems that the entire result is being queried first, which is not ideal when dealing with large data sets.
Question:
Is it possible to limit an Eloquent ORM query so that at the MYSQL Query level it also limits the result, equivalent to limit 3 offset 2?
User::find(1)->games()->take(3)->skip(2)->get();
I think this should give you your collection. :)
->games will give you a collection, where ->games() will offer a query builder instance.
Enjoy Laravel!