Doctrine/symfony: getSqlQuery() output in phpMyAdmin/SQL tab - symfony1

i have created this query that works OK:
$q1 = Doctrine_Query::create()
->from('Usuario u')
->leftJoin('u.AmigoUsuario a ON u.id = a.user2_id OR u.id = a.user1_id')
->where("a.user2_id = ? OR a.user1_id = ?", array($id,$id))
->andWhere("u.id <> ?", $id)
->andWhere("a.estado LIKE ?", 1);
echo $q1->getSqlQuery();
The calling to getSqlQuery outputs this clause:
SELECT s.id AS s__id, s.username AS
s__username, s.algorithm AS
s__algorithm, s.salt AS s__salt,
s.password AS s__password, s.is_active
AS s__is_active, s.is_super_admin AS
s__is_super_admin, s.last_login AS
s__last_login, s.email_address AS
s__email_address, s.nombre_apellidos
AS s__nombre_apellidos, s.sexo AS
s__sexo, s.fecha_nac AS s__fecha_nac,
s.provincia AS s__provincia,
s.localidad AS s__localidad,
s.fotografia AS s__fotografia,
s.avatar AS s__avatar,
s.avatar_mensajes AS
s__avatar_mensajes, s.created_at AS
s__created_at, s.updated_at AS
s__updated_at, a.id AS a__id,
a.user1_id AS a__user1_id, a.user2_id
AS a__user2_id, a.estado AS a__estado
FROM sf_guard_user s LEFT JOIN
amigo_usuario a ON ((s.id = a.user2_id
OR s.id = a.user1_id)) WHERE
((a.user2_id = ? OR a.user1_id = ?)
AND s.id <> ? AND a.estado LIKE ?)
If i take that clause to phpmyadmin SQL tab i get this error
1064 - 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 '? OR a.user1_id = ?) AND s.id <> ? AND a.estado LIKE ?) LIMIT 0, 30' at line 1
Why i'm getting this error?
Regards
Javi

The output includes placeholders in the query rather than actual values. You need to replace the ?'s with the correct values when you execute this in phpMyAdmin.
Using Symfony in dev mode, the values you're using for each query are shown in the database query panel accessible from the dev mode toolbar top right of your page, enclosed in parentheses after the query itself.

Related

How can you specify Oracle SQL functions such as trunc() in Rails select functions?

I have the below query written in a Rails controller which is querying an existing Oracle DB and it works fine.
#total_sales_volume = PaymentTransaction.joins(:settlement)
#total_sales_volume = #total_sales_volume.where("payment_transaction.transaction_status = 'S'
and payment_settlement.settlement_type = 'D'
and trunc(payment_settlement.transaction_date) > sysdate - 30")
However, I want to apply Oracle's trunc() function on the payment_settlement.transaction_date column. So I modified the above query and tried this:
#total_sales_volume = PaymentTransaction.joins(:settlement)
#total_sales_volume = #total_sales_volume.where("payment_transaction.transaction_status = 'S'
and payment_settlement.settlement_type = 'D'
and trunc(payment_settlement.transaction_date) > sysdate - 30").select("trunc(payment_settlement.transaction_date), payment_transaction.transaction_amount")
But no luck :( as I do not see any change in the actual query that gets fired. Here is the actual query that gets fired to Oracle (found it from the rails server logs)
SELECT
SUM("PAYMENT_TRANSACTION"."TRANSACTION_AMOUNT") AS sum_transaction_amount, transaction_date AS transaction_date
FROM
"PAYMENT_TRANSACTION" INNER JOIN "PAYMENT_SETTLEMENT" ON "PAYMENT_SETTLEMENT"."PAYMENT_TRANSACTION_ID" = "PAYMENT_TRANSACTION"."PAYMENT_TRANSACTION_ID"
WHERE
(payment_transaction.transaction_status = 'S'
and payment_settlement.settlement_type = 'D'
and trunc(payment_settlement.transaction_date) > sysdate - 30)
GROUP BY
transaction_date
Is applying Oracle SQL functions such as trunc() supported in ActiveRecord select functions?

Getting Conditional Count in Join with Laravel Query Builder

I am trying to achieve the following with Laravel Query builder.
I have a table called deals . Below is the basic schema
id
deal_id
merchant_id
status
deal_text
timestamps
I also have another table called merchants whose schema is
id
merchant_id
merchant_name
about
timestamps
Currently I am getting deals using the following query
$deals = DB::table('deals')
-> join ('merchants', 'deals.merchant_id', '=', 'merchants.merchant_id')
-> where ('merchant_url_text', $merchant_url_text)
-> get();
Since only 1 merchant is associated with a deal, I am getting deals and related merchant info with the query.
Now I have a 3rd table called tbl_deal_votes. Its schema looks like
id
deal_id
vote (1 if voted up, 0 if voted down)
timestamps
What I want to do is join this 3rd table (on deal_id) to my existing query and be able to also get the upvotes and down votes each deal has received.
To do this in a single query you'll probably need to use SQL subqueries, which doesn't seem to have good fluent query support in Laravel 4/5. Since you're not using Eloquent objects, the raw SQL is probably easiest to read. (Note the below example ignores your deals.deal_id and merchants.merchant_id columns, which can likely be dropped. Instead it just uses your deals.id and merchants.id fields by convention.)
$deals = DB::select(
DB::raw('
SELECT
deals.id AS deal_id,
deals.status,
deals.deal_text,
merchants.id AS merchant_id,
merchants.merchant_name,
merchants.about,
COALESCE(tbl_upvotes.upvotes_count, 0) AS upvotes_count,
COALESCE(tbl_downvotes.downvotes_count, 0) AS downvotes_count
FROM
deals
JOIN merchants ON (merchants.id = deals.merchant_id)
LEFT JOIN (
SELECT deal_id, count(*) AS upvotes_count
FROM tbl_deal_votes
WHERE vote = 1 && deal_id
GROUP BY deal_id
) tbl_upvotes ON (tbl_upvotes.deal_id = deals.id)
LEFT JOIN (
SELECT deal_id, count(*) AS downvotes_count
FROM tbl_deal_votes
WHERE vote = 0
GROUP BY deal_id
) tbl_downvotes ON (tbl_downvotes.deal_id = deals.id)
')
);
If you'd prefer to use fluent, this should work:
$upvotes_subquery = '
SELECT deal_id, count(*) AS upvotes_count
FROM tbl_deal_votes
WHERE vote = 1
GROUP BY deal_id';
$downvotes_subquery = '
SELECT deal_id, count(*) AS downvotes_count
FROM tbl_deal_votes
WHERE vote = 0
GROUP BY deal_id';
$deals = DB::table('deals')
->select([
DB::raw('deals.id AS deal_id'),
'deals.status',
'deals.deal_text',
DB::raw('merchants.id AS merchant_id'),
'merchants.merchant_name',
'merchants.about',
DB::raw('COALESCE(tbl_upvotes.upvotes_count, 0) AS upvotes_count'),
DB::raw('COALESCE(tbl_downvotes.downvotes_count, 0) AS downvotes_count')
])
->join('merchants', 'merchants.id', '=', 'deals.merchant_id')
->leftJoin(DB::raw('(' . $upvotes_subquery . ') tbl_upvotes'), function($join) {
$join->on('tbl_upvotes.deal_id', '=', 'deals.id');
})
->leftJoin(DB::raw('(' . $downvotes_subquery . ') tbl_downvotes'), function($join) {
$join->on('tbl_downvotes.deal_id', '=', 'deals.id');
})
->get();
A few notes about the fluent query:
Used the DB::raw() method to rename a few selected columns.
Otherwise, there would have been a conflict between deals.id
and merchants.id in the results.
Used COALESCE to default null votes to 0.
Split the subqueries into separate PHP strings to improve readability.
Used left joins for the subqueries so deals with no upvotes/downvotes still show up.

SQL EXISTS condition in Symfony 1.4

I'd like to express the following sql query in Symfony 1.4 using Doctrine's Query Builder :
select `user_agent`
from ticket
WHERE EXISTS (SELECT *
FROM log
WHERE ticket.id = log.ticket_id AND log.task_id = 1)
How I can express the "where exist....." condition?
You can use exists statement in where clause as other conditions. In your case it would look something like:
Doctrine_Core::getTable('ticket')->createQuery('t')
->select('user_agent')
->addWhere('exists(select * from log l where l.ticket_id = t.id AND l.task_id = 1')
->fetchArray();

ActiveRecord.joins adding unwanted sql

I am new to rails so forgive the question if its silly :S
I am using Spree as my e-commerce platform of choice.
In the Rails Console I run:
Spree::Product.joins(:product_properties, :taxons, :variants).limit(10)
this returns the sql:
SELECT `spree_products`.* FROM `spree_products` INNER JOIN `spree_product_properties` ON `spree_product_properties`.`product_id` = `spree_products`.`id` INNER JOIN `spree_products_taxons` ON `spree_products_taxons`.`product_id` = `spree_products`.`id` INNER JOIN `spree_taxons` ON `spree_taxons`.`id` = `spree_products_taxons`.`taxon_id` INNER JOIN `spree_variants` ON `spree_variants`.`product_id` = `spree_products`.`id` AND `spree_variants`.is_master = 0 AND `spree_variants`.deleted_at IS NULL LIMIT 10
However, I need the sql to set the values
`spree_variants`.is_master = 1 AND `spree_variants`.deleted_at IS NOT NULL
Does an one know how to do this? I have tried
Spree::Product.joins(:product_properties, :taxons, :variants).limit(10).where("`spree_variants`.is_master = 1 AND `spree_variants`.deleted_at IS NOT NULL")
but this doesnt work and generates the following sql
SELECT `spree_products`.* FROM `spree_products` INNER JOIN `spree_product_properties` ON `spree_product_properties`.`product_id` = `spree_products`.`id` INNER JOIN `spree_products_taxons` ON `spree_products_taxons`.`product_id` = `spree_products`.`id` INNER JOIN `spree_taxons` ON `spree_taxons`.`id` = `spree_products_taxons`.`taxon_id` INNER JOIN `spree_variants` ON `spree_variants`.`product_id` = `spree_products`.`id` AND `spree_variants`.is_master = 0 AND `spree_variants`.deleted_at IS NULL WHERE (`spree_variants`.is_master = 1 AND `spree_variants`.deleted_at IS NOT NULL) LIMIT 10
Thanks!
You'll save a lot of time by using squeel gem. It uses blocks extensively and allows you to write (among other features) queries like this on pure Ruby:
.where{(spree_variants.is_master == 1) & (spree_variants.deleted_at != nil)}
Note the using of square brackets and absence of symbols.
To use these features just add this line to your Gemfile:
gem 'squeel'
and run bundle install.

LINQ to SQL: making a "double IN" query crashes

I need to do the following thing:
var a = from c in DB.Customers
where (from t1 in DB.Table1 where t1.Date >= DataTime.Now
select t1.ID).Contains(c.ID) &&
(from t2 in DB.Table2 where t2.Date >= DataTime.Now
select t2.ID).Contains(c.ID)
select c
It doesn't want to run. I get the following error:
Timeout expired. The timeout period
elapsed prior to completion of the
operation or the server is not
responding.
But when I try to run:
var a = from c in DB.Customers
where (from t1 in DB.Table1 where t1.Date >= DataTime.Now
select t1.ID).Contains(c.ID)
select c
Or:
var a = from c in DB.Customers
where (from t2 in DB.Table2 where t2.Date >= DataTime.Now
select t2.ID).Contains(c.ID)
select c
It works! I'm sure that there both IN queries contain some customers ids.
In case this is an efficiency issue, it would be a good idea to look at the SQL query that LINQ to SQL produces (in debug mode, place the mouse cursor over a). In any case, you could try rewriting the query using join. Something like this should do the trick:
var a = from c in DB.Customers
join t1 in DB.Table1 on c.ID equals t1.ID
join t2 in DB.Table2 on c.ID equals t2.ID
where t1.Date >= DateTimeNow && t2.Date >= DateTimeNow
select c
It's not necessarily crashing but rather is likely producing an inefficient query that is timing out. A good thing to do is to run the SQL Server Profiler to see the actual query being emitted in SQL and then to do some analysis on that.
I found the problem. It's in my NEWID() order by method, because I want to get random results. When I remove it, it works fine. How can I use NEWID()?

Resources