I want to sum 4 cells for each row based on a previous query that will reduce the selection down to the important rows.
Basically I need to combine those two queries (which work on their own):
SELECT columnx, SUM(`column1`+ `column2` + `column3` + `column4`) as total
FROM table GROUP BY columnx
SELECT * FROM (SELECT * FROM table ORDER BY columny DESC LIMIT 5) t
ORDER BY CASE
when `pos` = 'PG' then 1
when `pos` = 'SG' then 2
when `pos` = 'SF' then 3
when `pos` = 'PF' then 4
else 5
end asc
I tried to replace "table" with the second query but it's probably not the right way, since I'm getting errors here.
SELECT columnx, SUM(`column1`+ `column2` + `column3` + `column4`) as total FROM
(( SELECT * FROM (SELECT * FROM table ORDER BY columny DESC LIMIT 5) t
ORDER BY CASE
when `pos` = 'PG' then 1
when `pos` = 'SG' then 2
when `pos` = 'SF' then 3
when `pos` = 'PF' then 4
else 5
end asc)
GROUP BY columnx
You were supposed to create an alias name for the block replacing table in your first query.
SELECT u.columnx, SUM(u.`column1`+ u.`column2` + u.`column3` + u.`column4`) as total
FROM (SELECT t.* FROM (SELECT * FROM table ORDER BY columny DESC LIMIT 5) t
ORDER BY CASE
WHEN t.`pos`='PG' THEN 1
WHEN t.`pos`='SG' THEN 2
WHEN t.`pos`='SF' THEN 3
WHEN t.`pos`='PF' THEN 4
ELSE 5
END ASC) u GROUP BY u.columnx
I have issue in one mysql query
Note I have checked all answer plz don't mark this question as repeat
i have one table with name of "questions" which contain que_id,cat_id, etc fields
I need to fetch 50 records from table which should be random 30 from cat_id=1 and random 20 from cat_id=2
I guess this should do it:
(SELECT * FROM questions
WHERE cat_id = 1
ORDER BY RAND()
LIMIT 30)
UNION ALL
(SELECT * FROM questions
WHERE cat_id = 2
ORDER BY RAND()
LIMIT 20)
(SELECT * FROM `questions` WHERE cat_id=2 and que_id >=
(SELECT FLOOR( MAX(que_id) * RAND()) FROM `questions` ) ORDER BY que_id LIMIT 20) UNION ALL
(SELECT * FROM `questions` WHERE cat_id=1 and que_id >=
(SELECT FLOOR( MAX(que_id) * RAND()) FROM `questions` ) ORDER BY que_id LIMIT 30)
I have a table with this structure:
id int
min int
max int
I want to order it ascendently and select the max of the first row, and the min of the second one.
So I did this query, and before I get the values that I need:
select min, max
from mytable
order by min asc
limit 2;
Also I tried this:
select cm_max
from mytable
order by cm_min
limit 1
union
select cm_min
from mytable
order by cm_min
limit 1,1;
But does not work...
There is any way to select only the fields I'll use?
If you want your values to be returned in one row you can do
SELECT MIN(CASE WHEN rnum = 1 THEN cm_max END) cm_max,
MIN(CASE WHEN rnum = 2 THEN cm_min END) cm_min
FROM
(
SELECT id, cm_min, cm_max, #n := #n + 1 rnum
FROM medidas, (SELECT #n := 0) n
ORDER BY cm_min
LIMIT 2
) q
What it does it gets two records with your order condition and assigns a row number to each row in the inner select. Then in the outer select we pivot whose values using CASE and row numbers.
or
SELECT q1.cm_max, q2.cm_min
FROM
(
SELECT id, cm_min, cm_max
FROM medidas
ORDER BY cm_min
LIMIT 1
) q1 CROSS JOIN
(
SELECT id, cm_min, cm_max
FROM medidas
ORDER BY cm_min
LIMIT 1, 1
) q2
In this query we grab two records of interest in sub queries and use CROSS JOIN to join two records and output needed values.
Here is SQLFiddle demo for both queries
Change your limit to 1,1 to select just the 2nd record from that set:
select cm_max as 'value'
from medidas
order by cm_min
limit 1
union
select cm_min as 'value'
from medidas
order by cm_min
limit 1,1;
Not sure if MySQL will complain about mis-matching field names, so aliases may or may not be needed.
Can somebody explain me this. My SQL:
SELECT
`offers`.`id`,
`offers`.`max_available`,
(SELECT COUNT( coupons.id ) FROM coupons WHERE coupons.status = 'Y' AND coupons.offer_id = offers.id) AS coupons_sold
FROM
`offers`
WHERE
`offers`.`status` IN ('P', 'S') AND
`offers`.`published_at` < 1341612000 AND
`offers`.`end_at` >1341567914 AND
`coupons_sold` < `offers`.`max_available`
ORDER BY `offers`.`created_at` DESC
LIMIT 4 OFFSET 0
This will return me these 4 rows:
id max_available coupons_sold
195 19 20
194 9999 0
193 9999 0
159 9999 93
How is possible that row with ID 195 is included, if I have this condition in where coupons_sold < offers.max_available? I am clueless!
This query would produce an error, as you can't use in WHERE clause, an alias from the SELECT list. Unless table offers has a coupons_sold column, too!
Try this query, instead:
SELECT id, max_available, coupons_sold
FROM
( SELECT
`offers`.`id`,
`offers`.`max_available`,
( SELECT COUNT( coupons.id )
FROM coupons
WHERE coupons.status = 'Y'
AND coupons.offer_id = offers.id
) AS coupons_sold
offers.created_at
FROM
`offers`
WHERE
`offers`.`status` IN ('P', 'S') AND
`offers`.`published_at` < 1341612000 AND
`offers`.`end_at` >1341567914
) AS tmp
WHERE coupons_sold < max_available
ORDER BY created_at DESC
LIMIT 4 OFFSET 0 ;
mytable
pid name field
=== ==== =====
1 A1 0
2 A2 1
3 A3 1
4 A4 0
5 A5 0
This is my table structure. Here I want to select randomly 4 rows so I use RAND() mysql function in my query
my questions is
How do I pair to rows. I mean, I wanna select pid 2 and 3 always one ofter another.
I need in bellow order. i don't want to break the pair A2 A3
A1 A2 A3 A4 or A2 A3 A4 A1 or A2 A3 A4 A5 or A4 A5 A2 A3 and etc
I used the query below but it's not working for me
SELECT * FROM mytable ORDER BY RAND() ASC limit 0,4
turbod was close with his answer, he was just ordering randomly, when it seems you wanted to order by pid, after getting the random rows you wanted in conjunction with the ones concerning A2 and A3:
(
SELECT *
FROM `mytable`
WHERE
name ='A2' OR
name ='A3'
LIMIT 2
)
UNION
(
SELECT DISTINCT *
FROM `mytable`
WHERE
name !='A2' OR
name !='A3'
ORDER BY RAND( ) LIMIT 2
)
ORDER BY `pid`
Generally, using ORDER BY RAND() is not a good idea. Please read the text by Jan Kneschke, showing why: http://jan.kneschke.de/projects/mysql/order-by-rand/
I ran a heavy test on this, passed.
(
SELECT * , 0.5 AS ordercol
FROM `mytable`
WHERE `name`IN ( "A2", "A3" )
LIMIT 2
)
UNION (
SELECT * , rand() AS ordercol
FROM `mytable`
WHERE `name` NOT IN ( "A2", "A3" )
LIMIT 2
)
ORDER BY ordercol, `name` IN ( "A2", "A3" ) , `name` ="A3"
This will do the job very well. But to make the result even more random, execute that statement with replacing that 0.5 value in 1st line with a random value chosen by your client application code like mt_rand(0, 1000000) / 1000000 in PHP . Make sure it falls between 0 and 1. But do NOT use mysql function rand() in place of that 0.5 because it will make A2 and A3 apart from each other. The trick is assigning a random value for "ordercol" in all rows but keep it same for A2 and A3
EDIT:
I believe we can replace the 0.5 value with a LEFT JOIN even instead of relying on discrete value by PHP, as we replace the first segment of the union, so the whole query becomes:
(
SELECT mt1.* , mt2.ordercol AS ordercol
FROM `mytable` AS mt1
LEFT JOIN (
SELECT RAND( ) AS ordercol
) AS mt2 ON TRUE
WHERE `name`
IN (
"A2", "A3"
)
LIMIT 2
)
UNION (
SELECT * , rand() AS ordercol
FROM `mytable`
WHERE `name` NOT IN ( "A2", "A3" )
LIMIT 2
)
ORDER BY ordercol, `name` IN ( "A2", "A3" ) , `name` ="A3"
I doubt there is a sane way to this in MySQL only.
I can think of one way of doing it, assuming you are using PHP/MySQL:
Essentially you query everything but A3, then put A3 next to A2
$res = mysql_query("SELECT name, field FROM mytable WHERE name <> 'A3' ORDER BY RAND()");
$res2 = mysql_query("SELECT name, field FROM mytable WHERE name = 'A3'");
$data = array();
while($row = mysql_fetch_array($res))
{
array_push($data, $row);
if ($row['name'] == "A2")
{
$row2 = mysql_fetch_array($res2);
array_push($data, $row2);
}
}
Now $data will contain your results in the desired order.
If you are always selecting all the rows in the table:
SELECT pid, name, field, idx
FROM (
SELECT pid, name, field,
#pos := IF(name = 'A3', #idx, #pos),
#idx := #idx + IF(name = 'A3', 2, 1), idx
FROM mytable, (SELECT #pos = -1, #idx := 0) dm
WHERE name <> 'A2'
ORDER BY RAND()
)
UNION SELECT pid, name, field, #pos + 1 idx
FROM mytable
WHERE name = 'A2'
ORDER BY idx;
If you are not always returning all the rows, thus need to check if A3 was returned to know if A2 should be included:
SELECT pid, name, field, idx
FROM (
SELECT pid, name, field,
#pos := IF(name = 'A3', #idx, #pos),
#idx := #idx + IF(name = 'A3', 2, 1), idx
FROM mytable, (SELECT #pos = -1, #idx := 0) dm
WHERE name <> 'A2'
ORDER BY RAND()
LIMIT 4
)
UNION SELECT pid, name, field, #pos + 1 idx
FROM mytable
WHERE #pos != -1 AND name = 'A2'
ORDER BY idx;
SELECT * FROM (
SELECT DISTINCT name FROM mytable
WHERE name <> 'A2' AND name <> 'A3'
ORDER BY RAND()
LIMIT 0,2
UNION
SELECT DISTINCT name FROM mytable
WHERE name = 'A2' OR name = 'A3'
ORDER BY name
)whateverQueryAlias
ORDER BY RAND()
That should do it.
Here is my solution:
SELECT *
FROM `mytable`
WHERE name ='A2'
OR name ='A3'
LIMIT 2
UNION
(SELECT DISTINCT *
FROM `mytable`
WHERE name !='A2'
OR name !='A3'
ORDER BY RAND( ) LIMIT 2) ORDER BY RAND()
SELECT *, RAND() "xrand" FROM yourtable A ORDER BY xrand LIMIT 4
SELECT * FROM `mytable` order by rand(), name asc limit 4.
i think this will satisfy your need.