Select a row where one column is min - php

I'm writing a simple URL rotator for a client and they want the URLs to rotate according to the oldest one that was previously displayed.
My columns are very simple:
url_id | company_id | url | last_clicked
I want to fetch a single row where the company_id is passed in and the last_clicked is the minimum of all records matching the company_id.
It should also select a random url_id if all last_clicked values are empty.
I assume this can be accomplished with a GROUP BY and HAVING but I can't seem to get the query to return anything.
I have this:
$last = $this->db->fetchOne ("SELECT url_id FROM
{$this->prefix}urls GROUP BY company_id HAVING MIN(last_clicked)
WHERE company_id='$company'");

This will fetch the row where last_clicked is smallest, or at random if they are all NULL:
SELECT url_id FROM urls
WHERE company_id = $company
ORDER BY last_clicked, RANDOM() LIMIT 1;
An index based on company_id and last_clicked would greatly help:
CREATE INDEX urls_ndx ON urls(company_id, last_clicked);

SELECT url_id FROM
TABLE
WHERE company_id='$company'
AND last_clicked = ( SELECT MIN(last_clicked)
FROM TABLE WHERE company_id='$company' )

Related

how to count rows starting at specific position

I want to count all rows that infront of a specific ID, so I can output how many entries are infront of the users entry.
I have no clue how to count the rows, starting at the ID of the user (for ex. ID 10).
How to count from ID 10 to ID 1 where status = unpublished
Thx
Are you looking for something like-
SELECT COUNT(*)
FROM your_table
WHERE ID BETWEEN 1 AND 10
AND STATUS = 'unpublished'
Try This --
SELECT COUNT(*)
FROM tablename
WHERE ID BETWEEN 1 AND 10
AND STATUS = 'unpublished'
ORDER by ID DESC
SELECT * FROM
WHERE ID = 10 AND status='unpublished';

FIFO type Recently Viewed Pages

I would like to create 20 rows of table data for to store recently viewed pages. The table row should not increase above 20 rows.
For an example, first 20 rows of page id with title will be stored in that table. when the 21st page viewed by the user, then the first post id and post title will be deleted (i.e., first viewed post) and insert (i.e., last viewed post) in the same table.
my table format:
-------------------------------|
ID | Post Title
-------------------------------|
1 | Post Title 1
2 | Post Title 2
3 | Post Title 3
...
20 | Post Title 20
-------------------------------|
if anyone please tell me how to do that with optimized qry.
You have two columns id and title. Let's consider that id will have any value even more than 20. At any time this table will contain maximums 20 rows (as per your need).
Understand following terms:
min(id) // will give minimum value in column id
max(id) // will give maximum value in column id
count(id) // counts total number of rows of your table
new_id // id of row which will be inserted next
Algorithm:
if(count(id)<20) // table have less than 20 rows so only insert
new_id = max(id)+1
insert the row with id as 'new_id' and page title
else // table have more than 20 rows so delete and then insert
delete row with id = min(id)
new_id = max(id)+1
insert the row with id as 'new_id' and page title
What above solution propose is if you have less than 20 rows keep on inserting because space is still there to insert. But, when you see that rows are more than or equal to 20 first delete the row with minimum id then insert the new row with maximum id of column by adding one.
You can do the following:
LOCK TABLES mytable;
INSERT INTO mytable (title) VALUES ('newtitle');
DELETE t FROM mytable t WHERE t.id IN (SELECT t2.id FROM (SELECT * FROM mytable) t2 ORDER BY t2.id DESC LIMIT 20,999999999); --Delete from 20 to "end"
UNLOCK TABLES;
First you need to add one column in table like created date
while inserting new record to this table, first check total number of rows in table
If rows count == 20 then write a query to delete one old record. use created_date to find it out...
if row count is < 20 then you can insert record directly...no pre-check required
Above step can be managed in only one query, If you are good at writing query
when user has viewed a page:
$query = mysqli_query("SELECT COUNT(ID) From your-table",$conn);
$result = mysqli_fetch_array($query);
$total = $row[0];
if($total<20){
//INSERT NEW ROW
$query = "INSERT INTO your-table() values(...,...)";
//etc ...
} else{
// DELETE THE FIRST ROW
$query = "DELETE FROM your-table ORDER BY ID ASC LIMIT 1";
// Then insert new row, etc...
}

Multiple Where clause using same columns SQL

I have table like this :
user_id field_id value
1 1 toto
2 1 tata
2 2 tata Job
user_id is the id of my users, field_id is the id of the information about the user (name, job, etc.) and value is the value.
I use a searchBar in HTML/PHP with 2 fields : 'name' and 'job'.
When someone search user using this two fields I need to retrieve the user id that matches these two conditions.
My question is :
How to get in SQL all user_id that match with two condition in one like this:
(field_id=1 and value=tata) AND (field_id=2 and value=tata's Job)
Thank you and have a good day !
SQL executes the WHERE logic for each row, not for the entire set. And fields cannot have more than one value. So, you need to use an OR statement instead of an AND to capture both conditions:
Select User_Id, Field_Id, Value
From YourTable
Where (field_id = 1 And value = 'tata')
Or (field_id = 2 And value = 'tata Job')
One method uses aggregation:
select user_id
from t
where (field_id = 1 and value = 'tata') or (field_id = 2 and value = 'tata''s Job')
group by user_id
having count(distinct field_id) = 2;
You can use IN statement, for example: Your table name is users
SELECT user_id
FROM users
WHERE field_id IN (1,2) AND `value` IN ('tata','tata\'s Job')

Selecting the next results in MySQL

How can I select the next result just by specifying the name?
I have a table that looks like this, no IDs, just list of usernames.
row1 = username(Alex)
row2 = username(Bob)
row3 = username(Britney)
row4 = username(Steve)
row5 = username(Courtney)
row6 = username(Greg)
row7 = username(Abul)
row8 = username(Roger)
row9 = username(Victoria)
row10 = username(Brooke)
Let's say, I want to select all Items after 'Greg'. How can I achieve this?
No, there is no inherent ordering of tables in SQL, so there is no way (other than by alphabetical order) to determine which name comes next.
In fact, the order displayed in the question is entirely arbitrary - without a specified order by clause, retrieval order of rows is essentially random.
this can be done by two query..first find the id of the particular name.
like select id from tablename where username='Greg'
then fetching that id,
select * from tablename where id>fetching id.
Add ID column to your table, and then use LIMIT as offset
SELECT * FROM users LIMIT (SELECT ID FROM username WHERE username='Greg'), MAX(ID)
Didn't tested, but you can play with it

How to get the last field in a Mysql database with PHP?

I have mysql database and I want to get the last ID from field in a table .
example : -
id Value
1 david
2 jone
3 chris
I want a function return 3 if this table exist .
You can use:
SELECT MAX(id) FROM table
If you want to select the ID of the most recently inserted row in a table with an AUTO_INCREMENT column, you will likey be interested in MySQL's LAST_INSERT_ID function.
SELECT id
FROM table
ORDER BY id DESC
LIMIT 1
you can also use the following code ::
$lastId = mysql_insert_id();
SELECT * FROM table ORDER BY id DESC LIMIT 1

Categories