In SQL, I might do something like this
"WHERE DATEPART(month, my_date_field) = 8"
to grab the rows where month in my_date_field = 8.
I am unsure how this syntax translates into Yii2.
I have
$query = Fees::find();
$fees = $query->all();
How do I use the WHERE clause on the date field within that $query ?
The query in yii2 allows text in where clause as below
$fees = Fees::find()
->where("DATEPART(month, my_date_field) = 8")
->all();
You may chain other 'sql functions' like order, group by , limit etc like this as well.
Related
I have written a query to fetch the data from mysql database using laravel query builder. Take a look at query builder code given below:
$products = DB::table("products as p")
->select("p.*")
->join("product_tag as pt", "pt.p_id", "p.id")
->whereIn("pt.tag_name", function($q1) use($request){
$q1->from("user_questionnaire as uc")
->select(DB::raw("distinct(at.prod_tag)"))
->join("questionnaire_answers as qa", function($join){
$join->on("qa.question_id", "=", "uc.question_id")
->where("qa.answer_number", "=", "uc.answer_id");
})
->join("answer_tags as at", "at.answer_id", "qa.id")
->where("uc.user_id", $request->user_id);
})->get();
When i log this query builder, i get below response:
[
{
"query": "select `p`.* from `products` as `p` inner join `product_tag` as `pt` on `pt`.`p_id` = `p`.`id` where `pt`.`tag_name` in (select distinct(at.prod_tag) from `user_questionnaire` as `uc` inner join `questionnaire_answers` as `qa` on `qa`.`question_id` = `uc`.`question_id` and `qa`.`answer_number` = ? inner join `answer_tags` as `at` on `at`.`answer_id` = `qa`.`id` where `uc`.`user_id` = ?)",
"bindings": [
"uc.answer_id",
115
],
"time": 0.43
}
]
Now when i run this query in phpmyadmin, it returns desired results. But when print_r $products variable, it displays empty array([]).
Please suggest what i am doing wrong in query builder.
Your problem is that you're using a ->where() to apply extra criteria to your innermost join:
->where("qa.answer_number", "=", "uc.answer_id");
In this case, the 3rd parameter is being bound into the query as a string so your database will be comparing the qa.answer_number field to the string uc.answer_id which is probably not what you're looking for. When you do a where, the 3rd (or the 2nd if you omit the operator) will always be added to the query bindings which is what results in this behaviour.
To get around this, you should use another ->on(...) to add additional criteria to the join:
$join->on("qa.question_id", "=", "uc.question_id")
->on("qa.answer_number", "=", "uc.answer_id");
That will make sure that the database is comparing columns to columns rather than columns to values.
can I convert this query
"SELECT * FROM (SELECT * FROM blog_post ORDER BY data DESC) blog_post GROUP BY blog_id LIMIT 2"
into a Yii2 active record query?
Thx
Ms
Yes, you can do this.
Yii2 gave us a wonderful library support.
You can form custom sql query and pass this query in findBySql() like:
$sql = "Some query/nested query";
$result = ModelClass::findBySql($sql);
Visit Yii official documentation.
BlogPost::find()
->orderBy('data DESC')
->groupBy('blog_id')
->limit(2)
->all();
I suppose you can do in this way :
Ⅰ:create a subQuery where you select from.
$blogPostQuery = BlogPostModel::find()->orderBy(['data' => SORT_DESC]);
Ⅱ:Get activeRecord results. The from params is an exist Query.
$models = (new yii\db\Query)
->from(['blog_post ' => $blogPostQuery])
->groupBy(['blog_id'])
->limit(2)
->all();
ps:
see yii\db\query->from()-detail in Yii Api;
(public $this from ( $tables )) $tables can be either a string (e.g. 'user') or an array (e.g. ['user', 'profile']) specifying one or several table names··· or a sub-query or DB expression
Have a try!I hope it`s useful for you:))
I need to perform this query:
SELECT * FROM (SELECT * FROM product WHERE car = 'large' ORDER BY onSale DESC) AS product_ordered GROUP BY type
In Symfony2 using the entity manager.
My basic query builder would be :
$query = $em->getRepository('AutomotiveBundle:Car')
->createQueryBuilder('p')
->where('pr.car = ?1')
->andWhere('pr.status = 1')
->orderBy('pr.onSale', 'DESC')
->setParameter(1, $product->getName())
->groupBy('p.type')
->getQuery();
But I cannot work out how to add in a subquery to this.
Ive tried making a separate query and joining it like:
->andWhere($query->expr()->in('pr.car = ?1',$query2->getQuery()));
But I get:
Call to undefined method Doctrine\ORM\Query::expr()
One trick is to build two queries and then use getDQL() to feed the first query into the second query.
For example, this query returns a distinct list of game ids:
$qbGameId = $em->createQueryBuilder();
$qbGameId->addSelect('distinct gameGameId.id');
$qbGameId->from('ZaysoCoreBundle:Event','gameGameId');
$qbGameId->leftJoin('gameGameId.teams','gameTeamGameId');
if ($date1) $qbGameId->andWhere($qbGameId->expr()->gte('gameGameId.date',$date1));
if ($date2) $qbGameId->andWhere($qbGameId->expr()->lte('gameGameId.date',$date2));
Now use the dql to get additional information about the games themselves:
$qbGames = $em->createQueryBuilder();
$qbGames->addSelect('game');
$qbGames->addSelect('gameTeam');
$qbGames->addSelect('team');
$qbGames->addSelect('field');
$qbGames->addSelect('gamePerson');
$qbGames->addSelect('person');
$qbGames->from('ZaysoCoreBundle:Event','game');
$qbGames->leftJoin('game.teams', 'gameTeam');
$qbGames->leftJoin('game.persons', 'gamePerson');
$qbGames->leftJoin('game.field', 'field');
$qbGames->leftJoin('gameTeam.team', 'team');
$qbGames->leftJoin('gamePerson.person', 'person');
// Here is where we feed in the dql
$qbGames->andWhere($qbGames->expr()->in('game.id',$qbGameId->getDQL()));
Kind of a long example but i didn't want to edit out stuff and maybe break it.
You can use DBAL for performing any sql query.
$conn = $this->get('database_connection');//create a connection with your DB
$sql="SELECT * FROM (SELECT * FROM product WHERE car =? ORDER BY onSale DESC) AS product_ordered GROUP BY type"; //Your sql Query
$stmt = $conn->prepare($sql); // Prepare your sql
$stmt->bindValue(1, 'large'); // bind your values ,if you have to bind another value, you need to write $stmt->bindValue(2, 'anothervalue'); but your order is important so on..
$stmt->execute(); //execute your sql
$result=$stmt->fetchAll(); // fetch your result
happy coding
I have two tables books and authors. Using CodeIgniter I would like users to be able to Filter results - for example, show results where author_id = 'x' and book_lang = 'y' and publication_year = '2000'. Filter criteria values come from user via drop-downs.
What's the best way to generate the query using codeigniter helper and binding etc?
For example, the query below will give me everything with author_id= 1. what if filters are a mix, for example; author_id = 1; language = 'all' (don’t put where clause on language) and publication year = 'all' also don’t put where clause.. Do I manually need to check for values and code or is there a codigniter helper method that allows filter to be removed from where clause if dropdown value is 'show all'?
$sql = "select * from AUTHORs a , BOOKS b where
a.AUTH_ID = b.BOOK_AUTH_ID
and b.BOOK_AUTH_ID = ?
and b.BOOK_LANGUAGE = ?
and b.PUB_YEAR = ? ";
$query = $this->db->query($sql, array ($author_id, $book_lang, $pub_year));
You should use Codeigniter's Active Record class to construct your query:
$this->db->select('*');
$this->db->from('AUTHORs a , BOOKS b');
$this->db->where('a.AUTH_ID', 'b.BOOK_AUTH_ID');
if ($author_id != 'all') $this->db->where('b.BOOK_AUTH_ID', $author_id);
if ($book_lang != 'all') $this->db->where('b.BOOK_LANGUAGE', $book_lang);
if ($pub_year != 'all') $this->db->where('b.PUB_YEAR', $pub_year);
$query = $this->db->get();
To read more about Codeigniter's Active Record class, visit the Docs:
http://codeigniter.com/user_guide/database/active_record.html
I'm new to Doctrine but somewhat familiar with SQL. I have a very simple schema with Users and Challenges. Each Challenge has a "challenger id" and a "opponent id" which are foreign keys into the User table. I want to print a list of all challenges, with the output being the names from the User table. Here is my Doctrine query;
$q = Doctrine_Query::create()
->select('u1.name challenger, u2.name opponent')
->from('Challenge c')
->leftJoin('c.Challenger u1')
->leftJoin('c.Opponent u2');
The problem is that this only returns one row. I've used the getSqlQuery() command to look at the generated SQL which ends up being:
SELECT u.name AS u__0, u2.name AS u2__1 FROM challenge c
LEFT JOIN user u ON c.challenger_id = u.id
LEFT JOIN user u2 ON c.opponent_id = u2.id
When run in a 3rd party SQL client this query retrieves all of the rows as expected. Any idea how I can get all of the rows from Doctrine? I'm using $q->execute() which I understand should work for multiple rows.
Thanks.
For me it worked by chaning the hydration mode:
$result = $query->execute(array(), Doctrine_Core::HYDRATE_SCALAR);
Set result set then returns an array instead of objects.
I just ran into this issue and in my case the problem was that my query didn't select any field from the FROM table. Example:
$query = Doctrine_Query::create()
->select(
'ghl.id as id,
ghl.patbase_id as patbase_id,
ghl.publication_no as publication_no,
ghl.priority_no as priority_no
'
)
->from('GridHitListContents ghlc')
->leftJoin('ghlc.GridHitList ghl')
As you can see there is no selected field from the GridHitListContents table.
with a $query->count() I got 2000ish results, but with $query->fetchArray() only the first one.
When I added
$query = Doctrine_Query::create()
->select(
'ghlc.id,
ghl.id as id,
...
'
)
->from('GridHitListContents ghlc')
->leftJoin('ghlc.GridHitList ghl')
I got back all my results.
$query->fetchOne() work fine for me.
Use this $result = $q->execute(array(), Doctrine_Core::HYDRATE_ARRAY)