Symfony2 - subquery within a join error - mysql

I would like to use a subquery inside a join, however Symfony2 throws the following error:
Here is my failed attempt:
$query = $em->createQuery(
'SELECT
sc.id AS id,
u.id AS userId,
u.username AS username,
sc_count.upvotes
FROM
myBundle:SuggestedCar sc
INNER JOIN myBundle:User u WITH sc.user_id = u.id
INNER JOIN ( SELECT sc1.user_id, COUNT(sc1.id) AS upvotes
FROM myBundle:SuggestedCar sc1
GROUP BY sc1.user_id
) sc_count WITH u.id = sc_count.user_id'
);
Basically I'm just joining 3 tables and the third one has a count. The query worked when executing it inside the database.
How would it be possible to use a SELECT statement inside a join? Is it a good idea to use raw SQL at this point?

The $em->createQuery() function is expecting DQL as the parameter, not SQL. If you want to execute a raw SQL statement, the syntax is different. You can do it like this:
$sql = "SELECT * FROM my_table";
$em = $this->getDoctrine()->getManager();
$stmt = $em->getConnection()->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll();
for more on DQL or querying for objects, see Querying for Object. The biggest difference is DQL will return an object (based on your entity classes in Symfony). The method I posted above will just give you a PDO result. So if you execute raw SQL, don't expect to be able to use the result as an object.
If you want to use raw SQL and still have the result mapped to an object, you can look at the doctrine docs about Result set mapping. In my opinion, this is more work than necessary.

Related

Get all data from 3 table in MySQL

I want to get all the data through the username from the 3 tables but I can not.
$username = $_GET['username'];
$res=$conn->query("select * from posts,tbl_view,tbl_user where posts.idpost=tbl_view.post_id AND
username='$username'");
Seems you missed the condition for join tbl_user with post.
Assuming your fk column is user_id, your query could be:
select *
from posts
INNER JOIN tbl_view ON posts.idpost=tbl_view.post_id
INNER JOIN tbl_user ON posts.user_id = tbl_user.id
WHERE tbl_user.username='$username'
You should not use the old join syntax based on comma separated table's name and where condition but use the explicit join syntax
And you should avoid the use of php var in sql. You should use prepared statement and parameter binding (to avoid SQL injection risk).

Delete entry with lowest ID

I just want to delete the row with the lowest ID.
I'm trying this:
$query = 'DELETE FROM PATH\TO\ENTITY ORDER BY id ASC LIMIT 1';
$query = $this->entityManager->createQuery($query);
$query->execute();
And getting this error:
[Syntax Error] line 0, col 53: Error: Expected end of string, got 'BY'
Maybe I'm using the wrong approach.
Any suggestions how to delete the entry with the lowest id in one database call?
As Kwido said, you miss the entity alias. But the query will still not be able to execute.
First, DQL does not support LIMIT expression. It is MySQL-specific feature, is not an ANSI SQL. Other platform drivers have an own implementations of this behavior, all of them provided by common interface: setFirstResult()/setMaxResult() of Query object.
Second, DQL does not support DELETE with ORDER BY clause (see language EBNF). It is non-standard feature too, but can not be implemented for other drivers, so Doctrine does not allow it.
If you need to execute this query, you will have to use a native SQL.
Define an alias for your entity as you use DQL. See: Doctrine - By DQL
$query = $this->entityManager->createQuery('SELECT e FROM MyEntity e ORDER BY e.id ASC');
$query->setMaxResults(1); // LIMITS 1
$entities = $query->getResult();
if (count($entities) > 0) {
$query = $this->entityManager->createQuery('DELETE FROM MyEntity e WHERE e.id = :identifier');
$query->setParameter("identifier", $entities[0]->getId());
$query->execute();
}
Replace entityAlias with the first letter of your entity classname, which is the most common practice with Doctrine.
// Edit - as #Timurib stated DQL doesn't know the LIMIT. Should've used setMaxResults.
// Edit2 - As ORDER BY is not supported by the DELETE statement, but only the WHERE clause. We're now using another query to return the identifier before deleting. See DQL - Statements
$query = 'DELETE FROM table ORDER BY id ASC LIMIT 1';
$stmt = $this->entityManager->getConnection()->prepare($query);
$stmt->execute();
You cannot delete or update from entityManager. First you have to select/find the entity from Repository and then remove it. My suggestion works for raw SQL query instead.

Need a SQL to Laravel Eloquent Translation

I need to translate the following SQL query into Laravel's Eloquent syntax:
SELECT a.*
FROM applications a
LEFT JOIN ratings r
ON a.id = r.application_id
AND r.admin_id = 1
WHERE r.admin_id IS NULL
The only way I've been able to get it to work is running the query using DB::raw, but I'm curious how it should look when using the Eloquent syntax. Ideally, I'd like to be able to migrate to any other database without a hiccup.
You can pass a closure to a join. You need to use DB::raw() as you're specifying a variable, rather than another database column to join on.
DB::table('applications')
->select('applications.*')
->leftJoin('ratings', function($join)
{
$join->on('ratings.application_id', '=', 'applications.id');
$join->on('ratings.admin_id', '=', DB::raw('1'));
})
->whereNull('ratings.admin_id')
->get()

Rails find_by_sql and parameter for id

Qucik question, why is the 2nd line of code working and the first not?
Detail.find_by_sql("SELECT * FROM details INNER JOIN players ON players.id = details.player_id WHERE players.team_id = ?", self.id)
Detail.find_by_sql("SELECT * FROM details INNER JOIN players ON players.id = details.player_id WHERE players.team_id = '#{self.id}'")
first line gives me MySQL error, looks like it doesn't pass the parameter to the SQL
Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1: SELECT * FROM details INNER JOIN players ON players.id = details.player_id WHERE players.team_id = ?
You have to use it like this :
Detail.find_by_sql(["SELECT * FROM details INNER JOIN players ON players.id = details.player_id WHERE players.team_id = ?", self.id])
Wanted to comment on AshwinKumarS's answer, but seems I have no rep points, so I have to post here. He gave the right answer, but with no explanation. Yes, find_by_sql only accepts a single array as its parameter. If you look at the API doc, it gives a wrong method signature (showing the sql parameter as independent of the bind array, but the samples below it are correct). I just wasted, like, an hour, trying to debug a problem caused by this (and of course it shows up as a MySQL syntax error rather than a Rails error - very confusing and frustrating!) Because this method only accepts a single, flat array, if you have many, or a variable number of parameters to pass, do it like this:
Detail.find_by_sql(["SELECT * FROM blah WHERE column1 = ? AND column2 in (?,?,?)", array_of_values].flatten)
find_by_sql supports only sql queries while you are using rails syntax
You should write your query in sql syntax like this:
Detail.find_by_sql("SELECT * FROM details INNER JOIN players ON players.id = details.player_id WHERE players.team_id = #{self.id}")
Or, you can also find it in rails syntax:
Detail.joins(:player).where("players.team_id = ?", self.id)

Zend_Db_Select - Joins and Count - Possible Zend Bug?

I'm having an issue getting a COUNT() from a SQL query using Zend_Db_Table_Select, and I think it may be a possible bug because the SQL it should be generating actually works. Here's the Zend Select Query: ($this is a Zend_Db_Table, renamed to table1 in this example)
$select = $this->select();
$select->setIntegrityCheck(false);
// Select Count
$select->from($this, array("COUNT(*) as 'COUNT'"))
->joinLeft('users', 'table1.userID = users.userID')
->joinLeft('table2', 'users.anotherKey = table2.anotherKey');
// Add Where clause after join
$select->where('users.anotherKey = ?', $anotherKeyValue);
This gives the error:
SQLSTATE[42000]: Syntax error or access violation: 1140
Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is
illegal if there is no GROUP BY clause`
However, this query...
SELECT COUNT(*) AS 'count' FROM table1
LEFT JOIN users ON table1.userID = users.userID
LEFT JOIN table2 ON users.anotherKey = table2.anotherKey
WHERE users.anotherKey = [anotherKeyValue]
...returns the expected results with no errors when run against the database. Any ideas whats going on, why the error, and how to get around it?
have you tried to see actual query, that zend_db produce?