I have the following query:
(SELECT ad_code, ad_zone FROM on_ads WHERE ad_zone = 1 AND status = '1' ORDER BY RAND() LIMIT 1) UNION (SELECT ad_code, ad_zone FROM on_ads WHERE ad_zone = 2 AND status = '1' ORDER BY RAND() LIMIT 1);
It's being logged as slow query in my server. I am trying to optimize it. I tried the following query
(SELECT ad_code, ad_zone FROM on_ads WHERE ad_zone = 1 AND status = '1' OR ad_zone = 2 AND status = '1' ORDER BY RAND() LIMIT 2)
But the problem with this query is that the first one was selecting two random rows, one with ad_zone=1 and the other with ad_zone=2. While mine selects two rows, but there is no guarantee it will select two different rows (One with ad_zone=1 and the other with ad_zone=2).
What should I do to optimize this query?
You have to try something like that:
(SELECT DISTINCT(ad_code), ad_zone FROM on_ads WHERE (ad_zone = 1 OR ad_zone = 2) AND status = '1' ORDER BY RAND() LIMIT 2)
Related
I have a table an_visit that has column visit_id. There is also a table an_transaction that has some visit_id too.
I would like to get a new column in MySQL based on if visit_id occurs in both tables. My approach:
SELECT visit_id, datetime_add, ISNULL((SELECT
1
FROM an_transaction
WHERE an_transaction.visit_id = an_visit.visit_id), 0)
FROM an_visit
WHERE datetime_add >= '2021-08-01'
LIMIT 50
But I got this error: MySQLdb.OperationalError: (1582, "Incorrect parameter count in the call to native function 'ISNULL'"). What do I do wrong, please?
SELECT visit_id, datetime_add, ISNULL((SELECT
1
FROM an_transaction
WHERE an_transaction.visit_id = an_visit.visit_id limit 1))
FROM an_visit
WHERE datetime_add >= '2021-08-01'
LIMIT 50
OR
SELECT visit_id, datetime_add, IFNULL((SELECT
1
FROM an_transaction
WHERE an_transaction.visit_id = an_visit.visit_id limit 1),0)
FROM an_visit
WHERE datetime_add >= '2021-08-01'
LIMIT 50
I am trying to figure it out but no solution at all.
My query :
SELECT * FROM table
WHERE owner = 'user'
AND (
CASE WHEN status = 'NEW'
THEN status = 'NEW'
ELSE status IN ('CB','NA','NI','GC','FC')
END
)
ORDER BY RAND() DESC
LIMIT 1;
What I want to achieve is to show all records where status is NEW in an Random order limited by one row each, when no records NEW for the user the query needs to show the other statuses.
Thank you.
SELECT * FROM Table
WHERE owner = 'user'
AND (CASE WHEN (SELECT COUNT(*) FROM Table WHERE status = 'NEW') >= 1 THEN
status = 'NEW'
ELSE status IN ('CB','NA','NI','GC','FC')
END)
ORDER BY RAND() DESC
LIMIT 1;
Demo
http://sqlfiddle.com/#!9/09b1c8/1
What i think, you can simply
SELECT * FROM table
WHERE owner = 'user'
AND (
CASE WHEN status = 'NEW'
THEN status = 'NEW'
ELSE status IN ('CB','NA','NI','GC','FC')
END
)
ORDER BY RAND() DESC
LIMIT 1;
To
SELECT * FROM table
WHERE owner = 'user' AND status IN ('NEW','CB','NA','NI','GC','FC')
GROUP By some_id
ORDER BY RAND() DESC
LIMIT 1;
SELECT * FROM table
WHERE owner = 'user'
AND status IN ('NEW', 'CB','NA','NI','GC','FC')
ORDER BY status = 'NEW' DESC,
RAND() DESC
LIMIT 1;
Will give you a total of 1 row, giving preference to a random 'NEW'. If no 'NEW' rows, then a random one of the others.
(Please clarify your Question and provide sample output.)
I am trying to query based on these conditions in an orders table,
// This is not an actual query
SELECT *
IF (store_id = 3) THEN ORDER BY WEIGHT DESC,
ELSEIF (STORE_ID = 7) THEN ORDER BY WEIGHT DESC
ELSEIF ORDER BY WEIGHT = DESC
ELSEIF (EQUAL WEIGHT) ORDER BY ORDER_DATE DESC
ELSEIF (EQUAL WEIGHT AND EQUAL ORDER_DATE) ORDER BY STORE_ID DESC
ELSEIF (EQUAL WEIGHT AND EQUAL ORDER_DATE AND EQUAL STORE_ID) ORDER BY
SHIPPING_METHOD DESC
FROM TABLE orders WHERE carrier_name = 'XXX'
This is as far as what I have got,
//Actual query
SELECT id,store_id,weight
FROM orders
WHERE carrier_name = 'XXX'
ORDER BY
IF(store_id = 3,weight,'')DESC,
IF(store_id = 3,order_date,'')DESC,
IF(store_id = 3,store_id,'')DESC,
IF(store_id = 3,shipping_method,'')DESC,
IF(store_id = 7,weight,'')DESC,
IF(store_id = 7,order_date,'')DESC,
IF(store_id = 7,store_id,'')DESC,
IF(store_id = 7,shipping_method,'')DESC,
IF(TRUE,weight,'')DESC,
IF(TRUE,order_date,'')DESC,
IF(TRUE,store_id,'')DESC,
IF(TRUE,shipping_method,'')DESC
The result obtained is
I am not sure why 53.39 and 30.35 are not sorted. What am I doing wrong?
Please suggest if there is a better way to attain this.
This is the required result,
Based on your expected output, the following query should give you what you want:
SELECT *
FROM orders
WHERE carrier_name = 'XXX'
ORDER BY CASE WHEN store_id = 3 THEN 0
WHEN store_id = 7 THEN 1
ELSE 2 END,
store_id,
weight DESC
For an explanation of the logic in the ORDER BY clause, the first condition puts store_id 3 first, followed by 7, followed by everything else. The next conditions orders each of these three groups in ascending order by the store_id. Note that for 3 and 7, this second step will be ignored, because the store_id value is the same for these groups (3 and 7 respectively). Finally, the third condition is to order by the weight in descending order.
ORDER BY
weight DESC, -- as i can see all true in your cases
order_date DESC,
store_id DESC,
shipping_method DESC
I got this error, I hope you may help me. I want to show a certain item in a search.
SELECT p.id, p.property_rank, p.pic_numb, p.att_numb, p.confirm, p.finalized ,p.deleted, p.user_id, p.add_date, p.visit_time,p.visit_date,p.sent_numb, p.contact_numb, zip_name, zip_id, p.street, p.sp_featured, p.property_title, p.b_price_unit, p.b_price_si, p.b_price, p.b_price, p.street_no, p.field_54,
p.field_409,
( SELECT `listing_type`.`id`
FROM `res_rpl_listing_types` AS `listing_type`
WHERE `listing_type`.`id` = (
SELECT `listing`.`type`
FROM `res_rpl_listings` AS `listing`
WHERE `listing`.`id` = p.`listing`)
) AS `listing_type_id`,
p.listing, p.googlemap_ln, p.googlemap_lt, p.category, p.b_bedrooms, p.b_bathrooms, p.sp_openhouse, p.b_price_period, p.b_lot_area_unit, p.b_lot_area_si, p.b_lot_area, p.b_lot_area, p.b_living_area_unit, p.b_living_area_si, p.b_living_area, p.b_living_area, p.description, p.sp_hot, p.sp_forclosure
FROM res_rpl_properties AS p
WHERE 1 AND p.`type` = '0' AND p.`confirm` = '1' AND p.`finalized` = '1' AND p.`deleted` = '0' AND p.`category` IN(9,8,10)
ORDER BY p.add_date DESC
LIMIT 0 , 12
The error is telling you that your subquery (selected as listing_type_id) returns more than one row. To rephrase - it's returning more than one value for listing_type_id. You should limit the results from the subquery to just one.
You have two options:
OR select just the first row of subquery
(SELECT `listing_type`.`id`
FROM `res_rpl_listing_types` AS `listing_type`
WHERE `listing_type`.`id` = (
SELECT `listing`.`type`
FROM `res_rpl_listings` AS `listing`
WHERE `listing`.`id` = p.`listing`
LIMIT 1
)
LIMIT 1
) AS `listing_type_id`
OR use IN to allow multiple comparation
(SELECT `listing_type`.`id`
FROM `res_rpl_listing_types` AS `listing_type`
WHERE `listing_type`.`id` IN (
SELECT `listing`.`type`
FROM `res_rpl_listings` AS `listing`
WHERE `listing`.`id` = p.`listing`)
LIMIT 1
) AS `listing_type_id`
The problem is there is 2 subqueries and you need to treat both. Both of them need to be limited to 1 row only.
I Have 2 tables, chamados(tickets) and atividades(activities) (1 for N)
Basically I need to select all 'chamados(tickets)' where last 'atividade(activity)' status is not 3 or 5;
I've tried within the SELECT and LEFT JOIN, nothing, I not got it yet.
My query is:
SELECT *
FROM (`chamados`)
ORDER BY `data_criacao_chamado` ASC
LIMIT 0,20;
I think that the query should seem something like:
SELECT *,
(
SELECT status FROM atividades WHERE atividade.fk_chamado = chamado.id_chamado ORDER BY id_atividade DESC LIMIT 1
) as status_item
FROM (`chamados`)
WHERE (status_item != 3 AND status_item != 5)
ORDER BY `data_criacao_chamado` ASC
LIMIT 0,20;
SELECT C.data_criacao_chamado FROM atividades A
JOIN
(SELECT fk_chamado, MAX(id_atividade) AS latest_atividade FROM atividades GROUP BY fk_chamado) LATEST_ATIVIDADES
ON A.fk_chamado = LATEST_ATIVIDADES.fk_chamado AND A.id_atividade = LATEST_ATIVIDADES.latest_atividade AND A.status_item NOT IN (3,5)
JOIN
chamados C ON C.id_chamado = A.fk_chamado