query execution is too long to load - mysql

can i minimize or shorter (if ever) this query? this query takes too long to load, how can I shorten the execution of this query? thanks.
this is my sql query:
$sql = "
SELECT
i.ID
FROM item_tb i
WHERE
i.coID = '". $_SESSION['coID'] ."'
AND i.isProduct = '1'
AND i.isBom = '0'
AND NOT EXISTS(
SELECT
s.ID
FROM
stocks_tb s
WHERE
i.ID = s.itemID
AND s.brID = '". $brID ."'
)
";

I guess that your query converted LEFT JOIN as follows:
SELECT
i.ID
FROM item_tb i LEFT JOIN stocks_tb s ON i.ID = s.itemID
WHERE
i.coID = '". $_SESSION['coID'] ."'
AND i.isProduct = '1'
AND i.isBom = '0'
AND s.brID = '".$brId."'
AND s.itemID IS NULL;
and this is faster than your query.

You use many AND operator... Use bracket within the AND condition.. That's it

Related

pdo add value to sql result

I use code below to get data from database
if( !empty( $books_ids ) )
{
$books_ids_in = implode(',', array_fill(0, count($books_ids), '?'));
$query = "SELECT
b.id,
b.`name`,
b.`year`,
GROUP_CONCAT(DISTINCT a.`name`) AS author_names,
GROUP_CONCAT(DISTINCT s.`name`) AS store_names
FROM
books AS b
LEFT JOIN books_authors AS b_a ON b.id = b_a.book_id
LEFT JOIN authors AS a ON a.id = b_a.author_id
LEFT JOIN books_stores AS b_s ON b.id = b_s.book_id
LEFT JOIN stores AS s ON s.id = b_s.store_id
WHERE
b.id IN (". $books_ids_in .")
GROUP BY b.id
ORDER BY b.id";
$stmt = $conn->prepare($query);
foreach ($books_ids as $k => $id) {
$stmt->bindValue(($k+1), $id);
}
$stmt->execute();
$results = $stmt->fetchAll();
}
and as I use $book id for this purpose, I would like to add some parameter in result to show that, for example, param = "book" for every row. Is there any way to do that?
Just pass it the string and alias it as a column. Though since you know the value passed in in code and display the values though code...... I'm not sure why you need this... as the value is available to you in the code when being displayed.
$query = "SELECT
b.id,
b.`name`,
b.`year`,
GROUP_CONCAT(DISTINCT a.`name`) AS author_names,
GROUP_CONCAT(DISTINCT s.`name`) AS store_names,
'". $param."' as forEveryRow
FROM
books AS b
LEFT JOIN books_authors AS b_a ON b.id = b_a.book_id
LEFT JOIN authors AS a ON a.id = b_a.author_id
LEFT JOIN books_stores AS b_s ON b.id = b_s.book_id
LEFT JOIN stores AS s ON s.id = b_s.store_id
WHERE
b.id IN (". $books_ids_in .")
GROUP BY b.id
ORDER BY b.id";

SELECT column/s based on boolean value

I have a left join select statement that I want to select specific columns based on the value of a variable that has either a '0' or a '1'. I thought I could implement this using CASE, but I don't seem to be having any luck.
If $variable contains a '0' I want my select statement to retrieve only users.user, table2.total1 and table2.total2, but if the $variable contains a '1' I want to select only users.user and table2.total.
$value = '1';
$conn->query(
"select users.user, table2.total, table2.total1, table2.total2
FROM users
LEFT JOIN table2 on users.user = table2.total AND $table2.date = CURDATE()
WHERE users.user = 'marketing' OR users.user = 'sales'
");
Does anyone have any ideas? Thanks.
You don't need to do this with sql, if in fact the query differ only by the select clause you could use a conditional and a variable:
$value = '1';
if($variable == '1') {
$select = "select users.user, table2.total1, table2.total2 ";
}
else {
$select = "select users.user, table2.total ";
}
$conn->query(
$select . "
FROM users
LEFT JOIN table2 on users.user = table2.total AND $table2.date = CURDATE()
WHERE users.user = 'marketing' OR users.user = 'sales'
");

MySQL QUERY runs on localhost, but does not on server

I have this QUERY:
select
a.*
from
mt_proyecto a,
mt_mockup b,
mt_diseno c,
mt_modulo d
where
a.estado = 'A' and
(
(b.encargado = '1' and b.idproyecto = a.idmtproyecto) or
(c.encargado = '1' and c.idproyecto = a.idmtproyecto) or
(d.encargado = '1' and d.idproyecto = a.idmtproyecto)
)
group by
a.idmtproyecto
order by a.finalizado asc, a.feccrea desc
Result:
Then, I run the same code on server with the same database:
Is there any problem with the query?
It seems that the query is running correctly on your server, and returning no rows. Please make sure you have the same table contents on your local machine and your server.
Other things:
Pro tip: never use SELECT * or SELECT table.* in software. Always enumerate the columns you want in your result set.
Unless you use GROUP BY with aggregate functions like SUM() or `COUNT(), and naming the correct columns from the result set, it returns unpredictable results. Read this. http://dev.mysql.com/doc/refman/5.1/en/group-by-extensions.html
I solved with this QUERY:
select
a.*
from
(
mt_proyecto a
left join mt_mockup b on
b.idproyecto = a.idmtproyecto
left join mt_diseno c on
c.idproyecto = a.idmtproyecto
left join mt_modulo d on
d.idproyecto = a.idmtproyecto
left join mt_integracion e on
e.idproyecto = a.idmtproyecto
left join mt_pruebas_internas f on
f.idproyecto = a.idmtproyecto
)
where
a.estado = 'A' and
(
(a.idmtproyecto = b.idproyecto and
b.encargado = '1' ) or
(a.idmtproyecto = c.idproyecto and
c.encargado = '1' ) or
(a.idmtproyecto = d.idproyecto and
d.encargado = '1' ) or
(a.idmtproyecto = e.idproyecto and
e.encargado = '1' ) or
(a.idmtproyecto = f.idproyecto =
f.encargado = '1' )
)
group by a.idmtproyecto
order by
a.finalizado asc, a.feccrea desc
Thanks everyone for answer me. I'll do your suggestions .

MYSQL multiply if?

I have a query that looks like this:
//execute the SQL query and return records
$result = mysql_query("SELECT SUM(ps_order_detail.product_weight) as total_provision, COUNT(ps_order_detail.id_order_detail) as antal_ordrar, ps_customer.firstname
FROM ps_order_detail
JOIN ps_orders ON ps_order_detail.id_order = ps_orders.id_order
JOIN ps_order_history ON ps_orders.id_order = ps_order_history.id_order
JOIN ps_customer ON ps_orders.id_customer = ps_customer.id_customer
WHERE MONTH(ps_order_history.date_add) = MONTH(CURDATE()) AND (ps_order_history.id_order_state) = '4' OR (ps_order_history.id_order_state) = '13'
GROUP BY ps_orders.id_customer
ORDER BY SUM(ps_order_detail.product_weight) DESC
");
//fetch tha data from the database
while ($row = mysql_fetch_array($result))
{
echo '<font size="3">';
echo " Namn: ".$row{'firstname'}. "";
echo " Provision: ".$row{'total_provision'}. "";
echo " Abonnemang: ".$row{'antal_ordrar'}. "";
echo '<br>';
echo '</font size>';
}
It works fine but what i wana do is if the result "antal_ordrar" is larger than say 50 i wana multiply the result "total_provision" with 1,2 (add an extra 20% to the result)
Im new on mysql and are kinda stuck. Any ideas?
SELECT SUM(ps_order_detail.product_weight) *
IF( COUNT(ps_order_detail.id_order_detail) > 50, 1.2, 1 ) AS total_provision,
COUNT(ps_order_detail.id_order_detail) AS antal_ordrar, ...
First, wrap this in a subquery:
SELECT
-- use the if statement
IF( antal_ordrar > 50, total_provision * 1.2, total_provision ),
antal_ordrar,
firstname
FROM
-- create a subquery so you can reuse the data.
( SELECT SUM(ps_order_detail.product_weight) as total_provision,
COUNT(ps_order_detail.id_order_detail) as antal_ordrar,
ps_customer.firstname as firstname
FROM ps_order_detail
-- are you sure you need this many joins?
JOIN ps_orders ON ps_order_detail.id_order = ps_orders.id_order
JOIN ps_order_history ON ps_orders.id_order = ps_order_history.id_order
JOIN ps_customer ON ps_orders.id_customer = ps_customer.id_customer
-- group by normally uses the 'having' keyword.
WHERE MONTH(ps_order_history.date_add) = MONTH(CURDATE())
AND (ps_order_history.id_order_state) = '4'
OR (ps_order_history.id_order_state) = '13'
GROUP BY ps_orders.id_customer
ORDER BY SUM(ps_order_detail.product_weight) DESC )
-- an alias for your subquery so you can treat it like a table.
tbl;
Just noticed this. You're using braces when you mean brackets: $row{'total_provision'} should be $row['total_provision'].
Try to add to select
if (antal_ordrar > 50, total_provision * 1.2, total_provision) as total_provision

mysql syntax how to add a third table to $query

I have code:
$query = "SELECT a.*, c.name as categoryname, c.id as categoryid
FROM #__table_one as a
LEFT JOIN #__table_two c ON c.id = a.catid";
$query .= " WHERE a.published = 1
AND a.access <= {$aid}
AND a.trash = 0
AND c.published =
AND c.access <= {$aid}
AND c.trash = 0";
I would like to add a third table ('__some_table') for the parts of the query where a.publish, a.access and a.trash. In other words, I want these fields to be retrieved from another table, not "#__table_one", but I do not know how to incorporate the #__some_table into the current query
I imagine the JOIN command can help me, but I do not know how to code mysql
//not tested
$query = "SELECT a.*, c.name as categoryname, c.id as categoryid
FROM #__table_one as a
LEFT JOIN #__table_two c ON c.id = a.catid
LEFT JOIN #__table_three d ON d.id = a.some_id";