Trying to add USE INDEX to MySQL statement - mysql

I have the below SQL statement and I am trying to add a USE INDEX clause to index on percent and doc_type which I have already added. No matter where I put the USE INDEX (ipercent,idoc_type) clause, it gives me an error say USE is in the wrong place. Any ideas?
select name,e_title
from
(select * from problem2.workson natural join
(problem2.documents,problem2.employees)) as newTable
where percent = 100
and (doc_type = 'internal-report'
or doc_type = 'external-report')
group by name
having count(name) > 1
Explain output:

Related

I have written query to sort name starting with S and V in give database , error coming up is below

select * from cricket_1111 , cricket_999
where first_name LIKE "s%v"
LIMIT 0, 1000
Error Code: 1052. Column 'first_name' in where clause is ambiguous 0.000 sec
You have a first_name column in both tables, so you have to specify which table you want to use like
select *
from cricket_1111 , cricket_999
where cricket_1111.first_name LIKE "s%v"
LIMIT 0, 1000
It would also be very productive if you took a look at the JOIN syntax rather than using from cricket_1111 , cricket_999
Something like
select *
from cricket_1111 c1
JOIN cricket_999 c9 on c9.link_column = c1.link_column
where c_1.first_name LIKE "s%v"
LIMIT 0, 1000
ORDER BY c_1.first_name
Also a limit clause without a sort ORDER BY can be very unpredictabe
Your error is due to the fact that the colum first_name appears in the two table. And the SQL engine cannot make an arbitrary choice ! You need to prefix the column name by the table name in the ORDER clause of the SELECT statement.

SQL - Nested query optimization

How can I optimize this query SQL?
CREATE TABLE table1 AS
SELECT * FROM temp
WHERE Birth_Place IN
(SELECT c.DES_COM
FROM tableCom AS c
WHERE c.COD_PROV IS NULL)
ORDER BY Cod, Birth_Date
I think that the problem is the IN clause
First of all it's not quite valid SQL, since you are selecting and sorting by columns that are not part of the group. What you want to do is called "select top N in group", check out Select first row in each GROUP BY group?
Your query doesn't make sense, because you have SELECT * with GROUP BY. Ignoring that, I would recommend writing the query as:
SELECT t.*
FROM temp t
WHERE EXISTS (SELECT 1
FROM tableCom c
WHERE t.Birth_Place = c.DES_COM AND
c.COD_PROV IS NULL
)
ORDER BY Cod, Birth_Date;
For this, I recommend an index on tableCom(desc_com, cod_prov). Your database might also be able to use an an index on temp(cod, birth_date, birthplace).

Select another column on IN query (subquery)

I have a query that gets a sku_product product that is sold on a precise date
SELECT stock_products.`related_warehouse_position_id`, `product_code`, `EAN_CODE`, `custom_cart_picked_up`, `warehouse`, sum(`RemainingStock`), stock_products.`time_Picked_up`
FROM `product_warehouse_position`
INNER JOIN stock_products ON product_warehouse_position.id = stock_products.related_warehouse_position_id
WHERE stock_products.time_Picked_up < '2017-10-10'
GROUP BY product_code
HAVING SUM(RemainingStock) = 0
Now i've tried with this query but the result is wrong.
I've try to make a subquery, but i need to get a time_pickedUp which is located on stock_products table.
SELECT `id` ,`product_code`, `EAN_CODE`, `custom_cart_picked_up`, `warehouse`, sum(`RemainingStock`)
FROM product_warehouse_position
WHERE product_code IN (
SELECT product_stock_sku, time_Picked_up
FROM `stock_products`
WHERE stock_products.time_Picked_up < '2017-05-01'
)
GROUP BY product_warehouse_position.product_code
HAVING SUM(product_warehouse_position.`RemainingStock`) = 0
This query return an error :
Operand should contain 1 column(s).
How to solve this problem without change the structure of this query?
If your query is correct then the only thing you need to do is remove the column time_Picked_up from the select in your inner query. You can still filter on that column in your WHERE clause.

Set a list in a variable in subquery - MYSQL

My problem is the following, I want set a list of ID in a variable, then use this variable in a subquery. The problem is that WorkBench (my GUI) return the following error : "subquery returning multiple rows". It seems to me that's what I want.
Please explain me where I am wrong.
This is my query :
set #listID := (select ID_VOIE as ID from voies
where ORIGINE = 'XXX'
group by CODE_INSEE, CODE_VOIE
having count(*) > 1);
select substring(v.CODE_INSEE,1,2), count(*) from voies v
where v.ID_VOIE in (#listID)
group by substring(vs.CODE_INSEE,1,2);
The thing is I'm blocked with the "group by", I want do a groupd by after a first group by, that's why I can't (or at least i didn't find a way) write the request with a single WHERE clause.
The thing is I know that I can put the whole request directly in my subquery instead of using variable but :
It can let me use this trick in another requests that needed this behaviour (DRY concept !)
I'm not sure but the subquery will be executed in each turn of my loop, and that will be very inefficient
So I seek 2 possible ways : a way that let me use a list in a variable in a subquery OR a way that let me use "group by" twice in a single query.
Thanks you in advance for your answers (oh and sorry for my english, this is not my maternal language).
Unless you need that variable for something else, you should be able to skip it entirely as follows:
SELECT
SUBSTRING(v.CODE_INSEE,1,2),
COUNT(*)
FROM
voies v
WHERE
v.ID_VOIE in
(SELECT
ID_VOIE as ID
FROM
voies
WHERE
ORIGINE = 'XXX'
GROUP BY
CODE_INSEE,
CODE_VOIE
HAVING COUNT(*) > 1)
GROUP BY
SUBSTRING(vs.CODE_INSEE,1,2);
As you say, the subquery will be executed for all rows. To avoid that, a variable would be best, but MySQL doesn't support table variables. Instead, you can use a temporary table:
IF EXISTS DROP TABLE myTempTable;
CREATE TEMPORARY TABLE myTempTable (ID_VOIE int); -- I don't know the datatype
INSERT INTO myTempTable (ID_VOIE)
SELECT DISTINCT -- using distinct so I can join instead of use IN.
ID_VOIE as ID from voies
WHERE
ORIGINE = 'XXX'
GROUP BY
CODE_INSEE, CODE_VOIE
HAVING COUNT(*) > 1
And now you can do this:
SELECT
SUBSTRING(v.CODE_INSEE,1,2), COUNT(*)
FROM
voies v
JOIN myTempTable tt ON
v.ID_VOIE = tt.ID_VOIE
GROUP BY SUBSTRING(vs.CODE_INSEE,1,2);

Help with complex mysql query

I have an existing mysql query that I need to add to and I'm not sure how to go about it.
Here is my current sql query.
SELECT tbl_brokerage_names.brokerage_id, tbl_brokerage_names.short_name,
b.indication, b.max_indication
FROM tbl_brokerage_names
LEFT JOIN (
SELECT * FROM tbl_recommendation_brokerages
WHERE recommendation_id = {$_GET['id']}
) b ON (tbl_brokerage_names.brokerage_id = b.brokerage_id)
ORDER BY tbl_brokerage_names.short_name ASC
Here is the query that I need to work into the previous query.
SELECT * , COUNT( * )
FROM tbl_streetaccounts
JOIN tbl_brokerage_names
WHERE tbl_brokerage_names.brokerage_id = tbl_streetaccounts.brokerage_id
Basically I need to return a count, so I need to combine these two queries.
You should run these as two separate queries.
The COUNT(*) query will return a single row, so there's no way to "combine" it with the first query while preserving the multi-row result of the first query.
Also, when you SELECT *, COUNT(*) you will get columns from some arbitrary row.
By the way, you have a glaring SQL injection vulnerability. Don't interpolate $_GET parameters directly in your SQL query. Instead, coerce it to an integer:
<?php
$id = (int) $_GET['id'];
$sql = "SELECT ... WHERE recommendation_id = {$id}";
Like #Bill said, you cannot get the count in every row without really weird syntax, but you can get an overall count using GROUP BY ... WITH ROLLUP.
e.g.:
<?php
$id = mysql_real_escape_string($_GET['id']); //works with anything, not just numbers
$query = "
SELECT tbl_brokerage_names.brokerage_id
, tbl_brokerage_names.short_name
, b.indication
, b.max_indication
, count(*) as rowcount
FROM tbl_brokerage_names
LEFT JOIN (
SELECT * FROM tbl_recommendation_brokerages
WHERE recommendation_id = '$id' //The single quotes are essential for safety!
) b ON (tbl_brokerage_names.brokerage_id = b.brokerage_id)
GROUP BY tbl_brokerage_names.brokerage_id WITH ROLLUP
ORDER BY tbl_brokerage_names.short_name ASC
";
The GROUP BY .. WITH ROLLUP will add an extra line to the result with all NULL's for the non aggregated columns and a grand total count.
If you have any lines where rowcount > 0 then you need to add extra clauses from table b to the group by clause to prevent MySQL from hiding arbitrary rows.
Table tbl_brokerage_names is already fully defined because you are grouping by the primary key.