PHP MySQL select random rows where a row is different - php

What Im Trying to achieve is selecting multiple rows randomly where a certain column is different from the last for example
SELECT * FROM mytable WHERE `column_for_duplicate_values` != '$thelastkey' ORDER BY RAND() LIMIT 10
the column for multiple values would hold for example:
1 , 1 , 1 , 1 , 2, 5 , 6, 6 , 6 , 6 , 6 , 11 , 11 , 11 , 19
and I want to select 1 from each. So I would get
1 , 2 , 5 , 6 , 11 , 19

The main problem with my solution may be that it's
slow
not applicable
You need to have a primary unique id in your mytable
SELECT * FROM mytable WHERE id IN (
SELECT id FROM (
SELECT id, column_for_duplicate_values
FROM mytable ORDER BY RAND()) AS rand
GROUP BY column_for_duplicate_values
ORDER BY RAND()) LIMIT 10;
The main concept is to first get a random list of all values with their id and the column you want to have unique values.
From this result we group by the value we only want to have once and only return the id. The main table will then select 10 random id's form this list.
I tried it with one of my db's. Should work with any table that has a unique id and some random other column.
If you append ORDER BY id ASC will also sort the id's.

Related

Split single row to multiple according to a number

Using the below select statement:
select
spec_sheet_color_comb.id,
spec_sheet_color_comb.pairs*2 as total
from
spec_sheet_color_comb
where
spec_sheet_color_comb.id_spec_sheet IN (4814)
And getting this result:
id total
79928 5
Now, I want to split this result according to the TOTAL quantity and get this result, 5 rows showing the ID:
Result
79928
79928
79928
79928
79928
It is really important, Thanks
Suppose you have a table having 2 columns id and total. (You can use your query instead of the table).
You need a collateral table (or view) with all the numbers 1..max_number_you_need
e.g.
(select 1 as number
union
select 2 as number
...
select 999 as number)
Then you can use the number source table joining your table you need to multiply rows
select id
from the_table t
join (table with numbers) n on n.number<=t.total
UPDATE: an example
SELECT id
from (select 1 as id, 5 as total
union
select 2 as id, 3 as total) t
join (select 1 as number
union
select 2 number
union
select 3 number
union
select 4 number
union
select 5 number) num on num.number<=t.total
order by id

select mysql from a row limit and asc php pdo

I have a table like below
ID
1
2
3
4
5
I want to select ID 2 then ASC LIMIT 3. I want to get 2,3,4.
My select goes.
SELECT * FROM TABLEID WHERE ID = 2 AND status = 'unuse' ORDER BY ID ASC LIMIT 3
But I only get 1 record I am expecting 3 row to be returned base on the LIMIT 3
I am expecting 3 row to be returned base on the LIMIT 3
You are expecting wrong, because LIMIT can not create records that aren’t there to begin with. You have only one record with ID=2, so a WHERE clause selecting those records of course only returns this one.
You want WHERE ID >= 2 to first select all records that have an id 2 or greater, and then limit that selection to 3 records only.
select * from TABLED limit 1,4
1 is offset start point
4 is upto count point
SELECT * FROM TABLEID WHERE ID BETWEEN 2 AND 4
OR exclude the id
SELECT * FROM TABLEID WHERE ID >=2 status = 'unuse' AND id <> 1 ORDER BY ID ASC LIMIT 3

mysql statement to get the rank of a given row id in an ordered result set

I have a mysql table with multiple columns. The primary key of the table is the 'id' column. A row has multiple columns but the most relevant one for this question is 'Date' which is basically a timestamp. What is an efficient way to get the order (rank) of a given row id if I want to order the rows by their timestamp. The most recent timestamp is of rank 1, the second is of rank 2 and so on. I want to return the rank of a given row
Edit: I use ORDER BY to get an ordered set but I want the mysql statement to return the order of the specific item, not an ordered rows. I also don't want to parse the result set since this is very time cosnuming
Edit2: for example assume the following table
id timestamp name
1 Dec 4, 2016 Bob
2 Jan 1, 2015 Eve
3 Feb 6, 2017 Alice
Given an id, I should return the order of the item
id=1, expected output: 2
id=2, expected output: 3 (least recent)
id=3, expected output: 1 (most recent)
answer with out edit :Use row_number () over (order by ) clause and put some *dummy
select ROW_NUMBER()over(order by (select1) ) as renk ,* from table
answer after edit in question..
select ROW_NUMBER()over(order by timestamp desc ) as renk ,* from table
Hi try this in mysql
SET #rank=0;
SELECT t.rank FROM
(SELECT #rank:=#rank+1 AS rank, id
FROM `table_name`
ORDER BY timestamp DESC) t WHERE t.id=5;
selct * from table where id>1 order by id asc limit 1
if( not date ){
selct * from table where id>0 order by id asc limit 1
}

mysql - get explicit value and random values in one query [duplicate]

This question already has an answer here:
Mysql Select some random rows and plus one specific row
(1 answer)
Closed 9 years ago.
Is it possible to get a specific value (like ID = 5) and in addition to that, two or three other random values from the same table?
Here's my query:
SELECT name, solution, MAX( solution )
FROM tracks
WHERE id !=5
GROUP BY name
ORDER BY RAND( )
LIMIT 0 , 30
What I want to do:
I have a quiz where I need to get three answers from the database. In my first query I'm getting the actual answer and in the second (the query above) I get the other two answer that are NOT the actual answer (ID != ).
The problem is, in my table, 4 values are the same, they have the same name, so if my acutal answer is ID = 5, there is the possibility that the query above will select the ID with 9 (it's the same name as ID = 5).
How can I avoid that?
Thank you!
Perhaps you could add a subquery to your where clause to lookup all solutions that are not the id and do not have the same solution name:
SELECT name, solution, MAX( solution )
FROM tracks
WHERE id !=5
--check that the id is not in the subquery and the name doesnt match:
AND id not in (select id from tracks t where id!=5 and t.name <> name)
GROUP BY name
ORDER BY RAND( )
LIMIT 0 , 30
Random results are random. If you want to ensure that you don't get results with the same name as the answer, you have to filter by name.
SELECT name, solution, MAX(solution)
FROM tracks
WHERE id != 5 AND name != (SELECT name FROM tracks WHERE id = 5)
GROUP BY name
ORDER BY RAND()
LIMIT 0 , 30
Yes, it's possible. Use UNION for that. (sqlfiddle here)
SELECT * FROM ( (
SELECT id, name, max(solution) as solution
FROM tracks
WHERE id = 5
GROUP BY name
LIMIT 0, 1
)
UNION (
SELECT id, name, solution
FROM tracks
WHERE id != 5
GROUP BY name
)) tmp ORDER BY RAND() LIMIT 0, 3

Ordering the SQL query in a particular order

Say i have a table Guest and it has column g_id : values 1 to 10.
Now i want the query to return me the g_id's neither in ascending order nor in descending..
but i want the 4th then 3rd and then 5th entry, in this particular order.
Also i want just the 4th 3rd and 5th entry.
say my entries have an id and a name . ;i.e. my table Guest has these two tables.
Now my table is as following.
1 A
2 B
3 C
4 D
5 E
6 F
7 G
8 H
9 I
10 J
Now i want just the entry with 4th 3rd and 5th g_id, and in this particular order.
How do i write the SQL query?
Thanks.
Select * from Guest ___________???
Kindly fill in the gaps.
You can use a CASE statement in your ORDER BY to use a fake column to sort on and a WHERE IN clause to only return the values you need.
SELECT *
FROM Guest
WHERE g_id IN (3, 4, 5)
ORDER BY
CASE WHEN g_id = 4 THEN 1
WHEN g_id = 3 THEN 2
WHEN g_id = 5 THEN 3
END
What is the order that deteremines whether something is 4th, 3rd or 5th? Without an ORDER BY clause, the data is returned in an indeterminate order by SQL. You cannot rely on the order that rows are entered or stored in the database table itself.
You can hard-code what you are asking like this:
select *
from Guest
order by case
when g_id = 4 then 1
when g_id = 3 then 2
when g_id = 5 then 3
else 4
end
One solution is the case statement:
select g_id from (
select g_id, case g_id
when 4 then 1
when 3 then 2
when 5 then 3
else 0
end virtcol
where virtcol != 0
order by virtcol
);
I'm not sure how set your ordering will be, but you can order by specifics:
ORDER BY
g_id = 4 DESC,
g_id = 3 DESC,
g_id = 5 DESC
You may be better off selecting the entries as they are and doing something like this in your php code:
$order = array('4 ', '3 ', '5 ');
$data = array();
while ($row = $result->fetch()) {
$data["$row->g_id "] = $row;
}
$data = array_merge(array_flip($order), $data);
I think that the answer mostly depends on the DBMS you are working on.
In Oracle the query below, even though inefficient, should work
select * from
(select * , rownum as order from guest order by id asc ) b
where b.order = 4
UNION
select * from
(select * , rownum as order from guest order by id asc ) b
where b.order = 3
UNION
select * from
(select * , rownum as order from guest order by id asc ) b
where b.order = 5
Not sure if something of more efficient is possible with a simple query,
i would use the monster above only and only if the table you are querying is very small.
You also have another option if the table is big and you have to extract only the first rows. In the case you described, I would retrieve the first 5 rows and then programmatically I would extract the rows in position 4,3,5.
you can extract the first 5 rows with this query in oracle
select * from guest order by id asc where rownum < 6
This query will get you the 3rd, 5th, and 4th items (limit 2, 1 means "retrieve starting with 3rd item, with total number retrieved = 1 records)
(select g_id from Guest limit 2,1)
UNION (select g_id from Guest limit 4,1
UNION (select g_id from Guest limit 3,1)

Categories