Converting SQL statement to Active Record syntax - ruby

I'm having some trouble figuring out the Active Record syntax for the following Postgres query:
SELECT *
FROM tracks
JOIN displays on displays.track_id = tracks.id
JOIN users on displays.user_id = users.id
WHERE user_id = 1
AND displays.display is true
AND tracks.likes_count > 200
The above query above works, and now I'm trying to convert it to activerecord's syntax but getting the error:
PG::SyntaxError: ERROR: syntax error at or near "'t'" LINE 1:
...ck_id" = "tracks"."id" WHERE (displays.display is 't', track...
Track.joins(:users, :displays).where('displays.display is ?, tracks.likes_count > ?, users.id = ?', true, 200, 1)
It seems like I'm doing something wrong with the displays.display is True statement, but I have tried a few variations to no avail.
I'm using Activerecord-4.2.0.
I would appreciate some insight.

By default ActiveRecord doesn't know how to join tracks and users, so indicate that you want to join through the displays:
Track.joins(:displays => :users).where('displays.display is true, tracks.likes_count > ?, users.id = ?', 200, 1)
Hope I remember syntax well :)

I think the problem is in the joins, you can try this:
Track.joins(displays: :users).where('displays.display = ?, tracks.likes_count > ?, users.id = ?', true, 200, 1)
You can make a join with a third table using the syntax:
Table1.joins(table2: :table3)
Result:
SELECT "table1".*
FROM "table1"
INNER JOIN "table2" ON "table2"."table_id" = "table1"."table1_id"
INNER JOIN "table3" ON "table3"."table2_id" = "table2"."table2_id"
able3" ON "table3"."table2_id" = "table2"."table2_id"
You can read more for ActiveRecord's joins method here: http://guides.rubyonrails.org/active_record_querying.html#joining-tables

Looks like I was actually just missing the ANDs....derp:
Track.joins(:users, :displays).where('displays.display = ? AND tracks.likes_count > ? AND users.id = ? ', true, 200, 1)
UPDATE Also as #Andrius pointed out Track.joins(:users, :displays) and Track.joins(:displays => :users) are two different joins and I want to use the former.

Related

Parse error: syntax error, unexpected 'F' (T_STRING), expecting ',' or ')'

`$data['top_argo'] = \DB::select( \DB::raw('select DISTINCT SUM(transaction.total) as total_argo, COUNT(transaction.id) as total_trans, users.name FROM transaction LEFT JOIN CUSTOMER ON customer.id = transaction.id_driver_fk LEFT JOIN users ON users.id = customer.id_user_fk WHERE id_customer_fk IS NOT NULL AND transaction.status = 'F' GROUP B`Y users.name ORDER BY SUM (transaction.total) DESC LIMIT 10'));
I need to run this query on my laravel, but I got an error like I said on the title. I'm new to laravel so can you help me?
Your query has lots of syntax errors. Don`t use double quotes without binding it a string.
data['top_argo'] = \DB::select( \DB::raw("select DISTINCT SUM(transaction.total)
as total_argo, COUNT(transaction.id) as total_trans, users.name FROM transaction
LEFT JOIN CUSTOMER ON customer.id = transaction.id_driver_fk
LEFT JOIN users ON users.id = customer.id_user_fk
WHERE id_customer_fk IS NOT NULL AND transaction.status = 'F' GROUP BY users.name ORDER BY SUM (transaction.total) DESC LIMIT 10"));
To fix the exception replace 'F' with \'F\'

Ecto Model - subquery in select

I need to make this SQL query with Ecto:
SELECT users.*, (select count(0) from money_transactions where from_id = users.id AND created_at > '2016-1-25 0:00:00.000000') as money_transactions_today_db FROM "users" WHERE "users"."client_token" = '123'
I try to do something like this but it doesn't work:
query = from users in Like4uElixir.User,
where: users.client_token in ^tokens,
select: {users, (from money_transactions in Like4uElixir.MoneyTransaction,
where: money_transactions.from_id == users.id,
select: count(0))}
Does Ecto support subqueries? If not, how can I execute the query?
You can use query fragments:
query = from users in Like4uElixir.User,
where: users.client_token in ^tokens,
select: {users, (fragment("(SELECT COUNT(0) FROM money_transactions
WHERE money_transactions.from_id == ?)", users.id))}
Although in this case the query can also be written using regular joins and group_by. Current support for subqueries in Ecto is limited.

Subqueries in Doctrine 1.2 DQL as FROM

Ok so the big deal is to get the rows in a mysql table that have another related row in the same table given some conditions. This table is like an activity log, so i want to notify someone that "some guy" leaved his group, but i only want do the notification when that guy joined the group before a given date, so what i do is the next sql:
SELECT ua.*, ua2.*
FROM user_activities AS ua
INNER JOIN (SELECT ua2.* FROM user_activities AS ua2
WHERE ua2.activity = "join-group"
ORDER BY ua2.created_at)
AS ua2 ON ua2.group_name = ua.group_name AND ua2.user_id = ua.user_id
WHERE ua.activity = "unjoin-group";
I omitted the date conditions due to clarity reasons.
So i need to know how to convert this to DQL (for doctrine 1.2), is it possible? or I better do it programatically?
What im trying now is this:
$q = Doctrine_Query::create()
->from('UserActivity ua, ua.User u ')
->where('ua.created_at > ?', $min_date)
->andWhere('ua.activity = ?', "unjoin-group")
->andWhereIn('u.status', array(STATUS_HOT, STATUS_ACTIVE))
->andWhere('ua.user_id IN ( SELECT
uaa.id
FROM
UserActivity uaa
WHERE
uaa.activity = ? AND
uaa.created_at < ? AND
uaa.created_at > ? AND
uaa.group_name = ua.group_name
LIMIT 1',
array("join-group", $min_date, $max_date));
But i get this error:
fatal error maximum function nesting level of '100' reached aborting
So i can't keep foward

Unknown column - multiple joins in CDbCriteria

I'm trying to get data from multiple tables and I've ended with this error:
SQL: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'p.firstname' in 'field list'
$criteria = new CDbCriteria;
$criteria->select = 'ohu_id, hash, p.firstname, p.surname, p.city, u.email AS Email';
$criteria->join = 'LEFT JOIN `profiles` p ON p.user_id = user_id';
$criteria->join = 'LEFT JOIN users u ON user_id = u.id';
$criteria->condition = 'offer_id = :oID';
$criteria->params = array(':oID' => $_GET['id']);
$model = MyModel::model()->findAll($criteria);
Anyone know what I'm doing wrong?
Or is there better way to get related data?
You are making the same mistake I made hehe.
You are overwriting the first join with the second one, instead of appending the second join.
$criteria->join = "join ...."; //first join
$criteria->join .= "join ...."; //second join
cheers
Actually its way better to user some "with" clause like this:
$criteria->with = array(
'profiles '=>array(
'select'=>'profiles.user_id',
'together'=>true
),
'users'=>array(
'select'=>'users.id',
'together'=>true
)
);
You can use this also in model searching for CGridView DataProvider.
It's better if you show your database structure. But here it's the solution to join multiple tables using left join
Code to join tables:
$criteria->select = 'ohu_id, hash, p.firstname, p.surname, p.city, u.email AS Email';
$criteria->alias = 'c';
$criteria->join = 'LEFT JOIN profiles p ON (p.user_id = c.user_id) LEFT JOIN users u ON (c.user_id = u.id)';
Hope it will help you.

Doctrine 1.2, running query over a Many to Many table

I want to make a query on an automatic generated table under Doctrine 1.2. In this particular case I have the following query:
SELECT F.id FROM ficha as F JOIN ficha_has_tema FT ON FT.ficha_id = F.id WHERE FT.tema_id = ? GROUP BY F.id HAVING COUNT(F.id) > 1
But I get the error:
Uncaught exception 'Doctrine_Exception' with message 'Couldn't find
class ficha_has_tema' in...
So, is there a way to make this query using doctrine without creating the class ficha_has_tema? I need to do the COUNT.
Thanks!
I assume you are executing DQL query here. It's impossible to use tables that have no associated entities wihthin the SQL queries.
However, you may run good-old SQL with
$q = Doctrine_Manager::getInstance()->getCurrentConnection();
$result = $q->execute("SELECT F.id FROM ficha as F JOIN ficha_has_tema FT ON FT.ficha_id = F.id WHERE FT.tema_id = ? GROUP BY F.id HAVING COUNT(F.id) > 1");
as suggested in "Using Raw SQL with Doctrine"
Or Doctrine Native SQL Support with something like (never tried that personally, might require some modification)
$q = new Doctrine_RawSql();
$q->select("{F.id}")
->from("
From ficha as F
JOIN ficha_has_tema FT ON FT.ficha_id = F.id
WHERE FT.tema_id = ?
GROUP BY F.id
HAVING COUNT(F.id) > 1"
);
$result = $q->execute(array($tema_id));

Resources