I have a query that follows this format:
(SELECT t.column1, t.column2
FROM table t
WHERE t.status = 1
LIMIT 10)
UNION
(SELECT t.column1, t.column2
FROM table t
WHERE t.status = 2
LIMIT 10)
The end result is that I need to have 20 rows. If the first SELECT statement can only find 9 rows with t.status = 1, then I would like the second SELECT statement to use LIMIT 11 instead of LIMIT 10
I am using PHP to write and run the query, but I am looking for something that will execute within MySQL so I can run it all as one query.
Any ideas would be greatly appreciated.
Add one more limit 'outside' with the total count and use the same for the limit of the 2-nd query.
(
SELECT t.column1, t.column2
FROM table t
WHERE t.status = 1
LIMIT 10 # 1/2 of total rows
)
UNION
(
SELECT t.column1, t.column2
FROM table t
WHERE t.status = 2
LIMIT 20 # total rows
)
LIMIT 20 # total rows
Related
I'm working on project for prizes draw in php and what is required for me is the following, I've 4000 user and the selection should goes as follows:
EMP_ID
------
1123
1420
1340
2301
2330
4430
4321
3456
3425
7753
4256
4895
as you see I have different number of users; and they ask me in every draw to select 1000 user, but the 1000 should be divided in equals between the employees Ids like selecting 200 row from the employees that start with 1 and other 200 from employees that starts with 2 and so on.
I accomplished this but with multiple selection statements, like select random 200 row from employees which starts with 1 and another SQL for employees which start with 2 and.....; is there any better solution that can accomplish this in one SQL statement?
if any one interested in #strawberry suggestion it would be like this
select x.* from
((SELECT a.`emp_id` FROM `emp_list` as a WHERE a.`flag` = '0' AND a.`emp_id` LIKE '1%' order by RAND() limit 200)
UNION
(SELECT b.`emp_id` FROM `emp_list` as b WHERE b.`flag` = '0' AND b.`emp_id` LIKE '2%' order by RAND() limit 200)
UNION
(SELECT c.`emp_id` FROM `emp_list` as c WHERE c.`flag` = '0' AND c.`emp_id` LIKE '3%' order by RAND() limit 200)
UNION
(SELECT d.`emp_id` FROM `emp_list` as d WHERE d.`flag` = '0' AND d.`emp_id` LIKE '4%' order by RAND() limit 200)
UNION
(SELECT g.`emp_id` FROM `emp_list` as g WHERE g.`flag` = '0' AND g.`emp_id` LIKE '7%' order by RAND() limit 200)
) as x order by RAND()
I have to execute a PHP code just one time to make some changes in my database to have better tables. The code is too heavy and send more than 190000 queries to database (both select and insert).
Now the problem is when I execute it on the browser, form the result on the database and words that I've set to echo to check if it is going in correct way, I can find that it is executed partly. No error/warning/notice appears on the page.
I set max execute time and all the related settings to 1hour but it just take 30minuts and stop the for loop at once.
this is a sample of a part of my code:
for ($i=9;$i<=19909; $i++){
$j=0;
$select= "select synonym from synonym where x_=". $i ."";
//echo $select;
//echo "</br>";
$select_result= mysqli_query($connection,$select);
if (mysqli_num_rows($select_result)>0) {
$row = mysqli_fetch_assoc($select_result);
$arra = explode("،",$row["synonym"]);
}
while ($arra[$j]){
$text=trim($arra[$j]);
$search="select word from semiresult where word='". $text ."'";
$search_result= mysqli_query($connection,$search);
if (mysqli_num_rows($search_result)==0) {
$insert="insert into semiresult (x, word, synonym) values ('','". $text."','".$syn."')";
}elseif (mysqli_num_rows($search_result)>0){
$repeat="UPDATE semiresult SET synonym=CONCAT(synonym,'".$syn2."') where word like'".$arra[$j]."'";
$repeat_result=mysqli_query($connection,$repeat) or die ('request "Could not execute SQL query" '.$repeat);
}
With work you could avoid doing much of this in php. Whether it is worthwhile would depend on the data and table declares.
For example, assuming that word has a unique index on it in the semiresult table and that the synonym field has at most 1000 delimited fields you could do something like this (untested):-
INSERT INTO semiresult (x, word, synonym)
SELECT '',
'". $text."',
SUBSRTING_INDEX(SUBSRTING_INDEX(t1.synonym, '،', (hundreds.aCnt * 100 + tens.aCnt * 10 + units.aCnt + 1)), '،', -1)
FROM synonym t1
CROSS JOIN
(
SELECT 0 aCnt UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) AS units
CROSS JOIN
(
SELECT 0 aCnt UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) AS tens
CROSS JOIN
(
SELECT 0 aCnt UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) AS hundreds
WHERE t1.x_ BETWEEN 9 AND 19909
AND LENGTH(t1.synonym) - LENGTH(REPLACE(t1.synonym, '،', '')) > (hundreds.aCnt * 100 + tens.aCnt * 10 + units.aCnt)
ON DUPLICATE KEY UPDATE synonym=CONCAT(synonym, VALUES(synonym))
after all I solve it!!
After changing time limitations like max execute time and any other time limitations to two hours in php settings I add this line of code at the begining of my code then it execute until the end of the code.
set_time_limit(0);
This code was planned to execute one time only otherwise I have not do this changes.
I have following MYSQL query:
select IF(`User`='101',`Friend`,`User`) as `Kto`,`Recent`
from `friends`
WHERE (`User`='101' || `Friend`='101') AND `Status`=1
HAVING `Kto` IN (SELECT `Id` FROM `users` WHERE `Id`=`Kto` AND `Online`>='100')
ORDER by Recent DESC limit 11
Using ORDER by Recent DESC query takes longer (Showing rows 0 - 10 (11 total, Query took 0.0090 sec) [Recent: 9337663 - 7683644])
If I do not use Order by, it is too mutch faster (Showing rows 0 - 10 (11 total, Query took 0.0005 sec))
In explain query with ORDER by shows filesort, which i guess is the slowness problem, see below:
Could you please help me, how to get rid of this filesort, or how to optimize this query, or help me to add proper index just for this query?
You can try this, mate:
SELECT
IF(f.`User`='101',f.`Friend`,f.`User`) as `Kto`,
f.`Recent`
FROM
`friends` f
INNER JOIN `users` u ON u.`Id` IN (f.`User`, f.`Friend`)
WHERE
(f.`User` = '101' || f.`Friend` = '101')
AND f.`Status` = 1
AND u.`Online` >= '100'
ORDER BY
f.Recent DESC
LIMIT 11;
I just want to perform multiple table operations in single query. The query is:
select name,sno , id as ids ,(select sum(amount) from client_credits
where user_id = ids) As total from clients where sno = '4' and total > '0'
This query is not working when I am trying use ** total > 0 **. Is there any other possibility ways? Please help me.
total is an alias. Aliases are not resolved when the WHERE clause is reached.
Try: where sno = 4 having total > 0
Alternatively, and more efficiently:
SELECT `c`.`name`, `c`.`sno`, `c`.`id`, SUM(`ccr`.`amount`) AS `total`
FROM `clients` AS `c`
JOIN `client_credits` AS `ccr` ON `c`.`id`=`ccr`.`user_id`
WHERE `c`.`sno` = 4
GROUP BY `c`.`id`
Notice how the total > 0 part is gone? That's because if there are no rows to join, then nothing will be joined and the rows are removed from the result ;)
I am trying to create a mysql query to select let's say 5 rows before and 5 rows depending on the currend ID. Here is the query I am trying to use:
SELECT * FROM posts WHERE PID<='10' ORDER BY PID DESC LIMIT 7
UNION ALL
SELECT * FROM posts WHERE PID>'10' ORDER BY PID ASC LIMIT 6
For some reason though, the query is not working. Am I missing something? I found this solution in a forum post.
Try this:
(SELECT *
FROM posts
WHERE PID <= '10'
ORDER BY PID DESC LIMIT 7
)
UNION ALL
(SELECT *
FROM posts
WHERE PID > '10'
ORDER BY PID ASC LIMIT 6
)
ORDER BY PID ASC;
sqlfiddle demo
The PID is likely of int type. So you should be using the following (SQL Fiddle):
(SELECT * FROM posts WHERE PID <= 10 ORDER BY PID DESC LIMIT 7)
UNION ALL
(SELECT * FROM posts WHERE PID > 10 ORDER BY PID ASC LIMIT 6)
As you can see the ordering of the two queries is also maintained separately.
DOCS
To apply ORDER BY or LIMIT to an individual SELECT, place the clause inside the parentheses that enclose the SELECT: