mysql - conditions in on vs conditions in where - mysql

I can't find a clear answer to this and my tests where inconclusive:
If I have a column in a table in a join that must be equal to (or in another relation with) a constant, is faster to put the condition in ON? Or at the end in WHERE?
Example:
SELECT * FROM `" . BLABLA . "` as `s`
JOIN `" . BLABLABLA . "` AS `sDet` ON (`sDet`.`a` > '" . $R['a'] . "'
AND '" . $R['b'] . "' BETWEEN `sDet`.`c` AND `sDet`.`d`
AND `s`.`id` = `sDet`.`idDet`
)
WHERE `s`.`f` = 'whatever'
Or
SELECT * FROM `" . BLABLA . "` as `s`
JOIN `" . BLABLABLA . "` AS `sDet` ON (`s`.`id` = `sDet`.`idDet`)
WHERE `s`.`f` = 'whatever'
AND '" . $R['b'] . "' BETWEEN `sDet`.`c` AND `sDet`.`d`
AND `s`.`id` = `sDet`.`idDet`
I was thinking first version should be faster but I'm not sure. Any thoughts?

I'm not quite sure whats quicker but do keep in mind that conditions are not always interchangeable between the where and on clause.
Inner join
In case of an INNER JOIN they are interchangable
Outer join
In case of an OUTER JOIN they are not necessarily interchangeable. It depends on which side of the join the conditions depends

Related

Using double and single quotes in wpdb select

I'm trying to construct a wp query that creates a string for each record:
$ttr_a = $wpdb->get_results("
SELECT CONCAT(
'"TR4":"',
t2.TaxAccount,
'", "',
CASE WHEN t1.TypeID = '1' THEN '"TR6":"Text A", '
WHEN t1.TypeID = '2' THEN '"TR6":"Text B", '
ELSE
CONCAT('"TR6":"', t1.NewID, '", ')
END
)
AS TID
FROM " . $wpdb->prefix . "table1 t1
LEFT JOIN " . $wpdb->prefix . "table2 t2
ON t1.NewID = t2.TaxCode
WHERE ID = " . $ID);
This query works fine in phpMyAdmin but the double quotes break the wpdb query. Is there some way to escape these? I've tried replacing with apostrophe and escaping the double qoutes with a double quote but nothing seems to work. If there are syntax errors here, please ignore them as I've just extracted what is needed, my sql query does work in mysql.
You should use a prepared statement here if at all possible. If that be not possible, then to escape literal double quotes inside a string defined with double quotes, try escaping the literal ones with backslashes:
$ttr_a = $wpdb->get_results("
SELECT CONCAT(
'\"TR4\":\"',
t2.TaxAccount,
'\", \"',
CASE WHEN t1.TypeID = '1' THEN '\"TR6\":\"Text A\", '
WHEN t1.TypeID = '2' THEN '\"TR6\":\"Text B\", '
ELSE
CONCAT('\"TR6\":\"', t1.NewID, '\", ')
END
)
AS TID
FROM " . $wpdb->prefix . "table1 t1
LEFT JOIN " . $wpdb->prefix . "table2 t2
ON t1.NewID = t2.TaxCode
WHERE ID = " . $ID);

Using variables on select query table name

i need to use dynamic table names on model select query like this:
$this->db->select("$this->table_car.id as carId, $this->table_car.price as carPrice, $this->table_car.name as carName, $this->table_car.used as carUsed, $this->table_car.visible as carVisible, $this->table_cat.name as catName, $this->table_brand.name as carBrand, $this->table_model.name as carModel");
But variable is not working. This is what I get:
SELECT .`id` AS `carId`, .`price` AS `carPrice`, .`name` AS `carName`, .`used` AS `carUsed`, .`visible` AS `carVisible`, .`name` AS `catName`, .`name` AS `carBrand`, .`name` AS `carModel`
LEFT JOIN ON .`car_id` = .`id`
LEFT JOIN ON .`id` = .`cat_id`
LEFT JOIN ON .`id` = .`brand_model_id`
LEFT JOIN ON .`id` = .`model_id`
LEFT JOIN ON .`id` = .`brand_id`
WHERE .`used`= 0 LIMIT 3
Is there a workaround for this?
Thanks in advance
Whilst double quotes do allow the use of variables inside them without the need to close and concatenate, it doesn't always work for the likes or object and arrays, like you are showing. A better solution would be:
$this->db->select($this->table_car . ".id as carId, "
. $this->table_car . ".price as carPrice, "
. $this->table_car . ".name as carName, "
. $this->table_car . ".used as carUsed, "
. $this->table_car . ".visible as carVisible, "
. $this->table_cat . ".name as catName, "
. $this->table_brand . ".name as carBrand, "
. $this->table_model . ".name as carModel");
Another option would be to put your object variables in braces {} such as :
$this->db->select("{$this->table_car}.id as carId,
{$this->table_car}.price as carPrice,
{$this->table_car}.name as carName,
{$this->table_car}.used as carUsed,
{$this->table_car}.visible as carVisible,
{$this->table_cat}.name as catName,
{$this->table_brand}.name as carBrand,
{$this->table_model}.name as carModel");

Adapt MySQL query to JDatabase query

I am trying to execute a query through Joomla 2.5.
By using the following MySQL query, it performs correctly:
$query = "REPLACE INTO fa_usr (id, date_time, usr, clu) SELECT NULL, NOW(), " . $usr . ", " . $clu . " FROM DUAL WHERE (SELECT COUNT(*) FROM fa_use_clu WHERE usr=" . $usr . " AND clu=" . $clu . ") < 1";
Now, as I'm trying to use JDatabaseQuery methods, how the above mentioned query could be transformed correctly?
I have checked this link, which is from the official documentation, but seems I cannot find an appropriate solution.
Any ideas?
Thanks!

How to return largest value of the selected row?

I'm trying to select latest date in row (not in column)
It must be 'articles_date_added' or 'articles_last_modified' in table like that
Id | ... | ... | articles_date_added | articles_last_modified | ...
My real query looks like:
select
a.articles_id, a.authors_id, a.articles_date_added,
a.articles_last_modified,
IF(a.articles_last_modified >= a.articles_date_added,
a.articles_last_modified,
a.articles_date_added) as latestdate,
ad.articles_viewed,
ad.articles_name, ad.articles_head_desc_tag,
COUNT(vh.articles_id) as total_votes,
SUM(v.vote_value)/COUNT(v.vote_value) AS vote_avg,
au.authors_name, td.topics_name, a2t.topics_id
from
" . TABLE_ARTICLES . " a
left join " . TABLE_AUTHORS . " au using(authors_id)
left join VOTE_HISTORY vh using (articles_id)
left join VOTE v using (vote_id),
" . TABLE_ARTICLES_DESCRIPTION . " ad,
" . TABLE_ARTICLES_TO_TOPICS . " a2t
left join " . TABLE_TOPICS_DESCRIPTION . " td using(topics_id)
where
(a.articles_date_available IS NULL or
to_days(a.articles_date_available) <= to_days(now())) and
a.articles_status = '1' and a.articles_id = a2t.articles_id and
ad.articles_id = a2t.articles_id and
ad.language_id = '" . (int)$languages_id . "'
and td.language_id = '" . (int)$languages_id . "'
and a2t.topics_id = '" . (int)$current_topic_id . "' and
au.authors_id = '" . (int)$_GET['filter_id'] . "'
GROUP BY a.articles_id
ORDER BY latestdate desc
As you can see to select it I use
IF(a.articles_last_modified >= a.articles_date_added,
a.articles_last_modified, a.articles_date_added) as latestdate
but it returms 1054 - Unknown column 'latestdate' in 'order clause
Why?
I'm on MySql 5.0.
Since adding is a modification, it'd be a good idea if your a.articles_last_modified would contain the same date as a.articles_date_added upon inserting a row.
UPDATE `articles`
SET `articles_last_modified` = `articles_date_added`
WHERE `articles_last_modified` = '0000-00-00 00:00:00'
ALTER TABLE `articles`
CHANGE COLUMN `articles_last_modified` `articles_last_modified`
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
This way you won't need this condition in where clausule

Query multiple fields in sql query using same variable

I have the query below which works great.
SELECT `Despatch`.`DespatchNumber` , `Despatch`.`Product` ,
`Stock`.`ProductNumber` , `Stock`.`Description` ,
`Stock`.`ProductGroup` , `Stock`.`Size` , `Stock`.`IPICODE` , `Stock`.`Fit` ,
`Stock`.`62`
FROM Stock , Despatch
WHERE `Despatch`.`DespatchNumber` = '" . $Despatch . "'
AND `Despatch`.`Product` = `Stock`.`ProductCode`
My problem is i want to expand it that im using the value of $Despatch to search another column in the same table using an OR function. So the query will look into Despatch Number and if it does not find one matching then it looks into order number as below. It doesnt work and my mysql server just hangs trying to run this query.
SELECT `Despatch`.`DespatchNumber` , `Despatch`.`Product` ,
`Stock`.`ProductNumber` , `Stock`.`Description` , `Stock`.`ProductGroup` , `Stock`.`Size` , `Stock`.`IPICODE` , `Stock`.`Fit` , `Stock`.`62`
FROM Stock , Despatch
WHERE `Despatch`.`DespatchNumber` = '" . $Despatch . "'
OR `Despatch`.`OrderNumber` = '" . $Despatch . "'
AND `Despatch`.`Product` = `Stock`.`ProductCode`
You need parentheses around your OR clause:
WHERE (`Despatch`.`DespatchNumber` = '" . $Despatch . "'
OR `Despatch`.`OrderNumber` = '" . $Despatch . "')
AND `Despatch`.`Product` = `Stock`.`ProductCode`
I'd also very strongly recommend you to explicitly use the JOIN keyword when you perform joins. Not only is this best practice, but it also would have prevented the error occuring in this case.
SELECT -- ...columns...
FROM Stock AS S
JOIN Despatch AS D
ON D.Product = S.ProductCode
WHERE D.DespatchNumber = 'DN001234'
OR D.OrderNumber = 'DN001234'