SQL Get max ID grouped by a second ID - php

I am working on a php/mysql best before date checking system and upon creating a new check I need the system to find a best before date for a certain product by looking for it most recent closed check
I am working with a few tables to get this done:
bbcheckProducts
ID checkID productID checked bestBefore
1 1 1 1 2015-05-06
2 2 1 1 2016-07-22
3 3 1 1 2016-09-16
bbChecks
checkID userID closed
1 1 1
2 2 1
3 1 1
So when I run this query on the tables in the image above:
SELECT ID,
MAX(checkID) AS maxCheck,
bestBefore
FROM bbcheckProducts
WHERE checkID IN
(
SELECT checkID
FROM bbChecks
WHERE userID = 1
AND closed = 1
)
AND checked = 1
GROUP BY productID
ORDER BY bestbefore ASC
it returns something like this:
ID = 1
maxCheck = 3
bestBefore = 2015-05-06
so it does take the max checkID but the other values remain equal to the first occurence of productID. I want it to take the values that go together with that max ID so the result would look like this:
ID=3
maxCheck = 3
bestBefore = 2016-09-16
so how do I get my query to work like that?
NOTE: there are multiple products so product one may be in check 1 and 3 while product 2 is only in 1 so it has to take the data of product 2 from check 1 and the data of product 1 from check 3

You need to use max function on second table like this query
select * from table_name where some_colomn = 'some_value' and some_colomn
in (select max(some_colomn) from table_name2 where some_col = 'some_value' group by some_colomn)

You could join your tables to get a reduced set of all record with an check_ID existing in your bbChecks-table.
Then you can run your max(CheckID)-selection on the reduced set.
In your case this would like like that:
SELECT ID, max(checkID), bestBefore
FROM bbcheckProducts p
INNER JOIN bbChecks c ON (p.checkID = c.checkID)
WHERE UserID = 1
AND closed = 1
AND checked = 1
This returns you first of alle the records with the checkIDs 1 and 3. And then you select the max(checkID), so it returns you the checkID 3.

Related

Finding the most repeating id by laravel eloquent group

$device = SalesItem::where('type', '=', 1)->get()->groupBy('product_id');
There is a list of products in the database. Here I am storing the product id. The same product can be idsi. I want to get the id data of the product with the same id at most.
Sample:
ID type product_id
1 1 1
2 1 1
3 1 1
4 1 1
5 1 1
6 1 2
7 1 2
8 1 1
9 1 1
0 1 1
output: 1
here I want the output to give product id 1. I couldn't find what to do after group by. Can you guide me on this?
I don't think there is an elegant way to do this in, but this should work for you:
Note: I'm unsure of your table name.
$device = DB::table('sales_item')
->select('product_id', DB::raw('COUNT(product_id) AS magnitude'))
->where('type', 1)
->groupBy('product_id)
->orderBy('magnitude', 'DESC')
->limit(1);
It goes into the table and selected the id, type, and the COUNT() of product_id. Which it then groups by the product_id and orders by the count('product_id') from high to low.
->limit(1) is used to only select the first (read highest) value.

Number of 1 time,2 times, 3 times, n times column entries in table in php mysql

Have Table :
id userid type created_date
1 4353535 1 04-06-2014
2 4353536 0 06-06-2014
3 4353537 1 11-06-2014
4 4353538 1 11-06-2014
5 4353539 0 19-06-2014
7 4353541 1 01-06-2014
10 4353544 1 12-06-2014
11 4353535 1 06-06-2014
12 4353536 1 10-06-2014
13 4353537 1 12-06-2014
What I Want : (with in date range)
How much user have single time entry with type 1
How much user have double time entry with type 1
How much user have triple time entry with type 1
How much user have four time entry with type 1
How much user have n time entry with type 1
(PHP & MYSQL)
First get the count for each user, then from that group the entrycount you can get your expected output
select EntryCount, count(userid) from (Select userid, count(id) as Entrycount from myentry group by userid where type=1) as sq group by Entrycount
This will work try
First, get the number of entries per user. Then, get the number of users grouped by number of entries.
SELECT numEntries, COUNT(*) AS numUsers
FROM (
SELECT userid, COUNT(*) AS numEntries
FROM tablename
WHERE type = 1
GROUP BY userid
) tbl
GROUP BY numEntries
Simplified demo
Demo with your data

How can I select all the values of a database and choose one of them by a percent

What I want to do is to select a value of the database,
Lets say:
id ---- giftid ---- userid
1 1 481
2 1 422
3 7 123
4 9 542
5 1 122
6 1 455
For example, there are 4 users that want to have the same giftid:
1, 2, 5, 6
It means that each one will have 25% to be chosen.
How can I make the "percent selection"?
Assuming every userid can only claim a giftid once, you can use the ORDER BY RAND() in MySQL. This will firstly select all the rows from table table where the giftid is 1 and then the results are ordered randomly. The LIMIT 1 ensures that only the first record is returned
SELECT * FROM table
WHERE giftid = `1`
ORDER BY RAND()
LIMIT 1
Are you looking this?
SELECT giftid, 1.0 / COUNT(*) percentSelection
FROM tableName
GROUP BY giftid

Help with limiting a joined mysql database query

I have written a query which returns all records with some many-to-many joins correctly for the entire set or an individual article using WHERE a.id = ?
SELECT a.id, date_added, title, content, category_id, person_id, organization_id, c.name AS category_name, firstname, lastname, o.name AS organization_name
FROM articles AS a
LEFT OUTER JOIN articles_categories AS ac ON a.id=ac.article_id
LEFT OUTER JOIN categories AS c ON c.id=ac.category_id
LEFT OUTER JOIN articles_people AS ap ON a.id=ap.article_id
LEFT OUTER JOIN people AS p ON p.id=ap.person_id
LEFT OUTER JOIN articles_organizations AS ao ON a.id=ao.article_id
LEFT OUTER JOIN organizations AS o ON o.id=ao.organization_id
ORDER BY date_added
BUT!
I've hit a brick wall trying to work out how to limit the articles to a specific number of IDs, for working with pagination.
I'm ideally trying to use as simple and clear SQL statements as possible because I'm using the codeigniter framework with their active record class.
http://codeigniter.com/user_guide/database/active_record.html
Would really appreciate some help as I don't want to revert to using multiple queries for this as I've tried to reduce it down to a single query for database efficiency.
Have search around and tried some alternatives but nothing seems to work. Many thanks!
For example the results I return are like this
---------------------------------------------------------------------
id title category_id person_id organization_id
---------------------------------------------------------------------
1 test 1 1 1
1 test 2 1 1
1 test 1 2 1
1 test 1 1 2
1 test 5 1 1
1 test 8 1 1
1 test 1 4 1
1 test 1 4 2
1 test 1 1 1
2 test 2 2 1 1
2 test 2 1 2 1
2 test 2 1 1 2
2 test 2 5 1 1
2 test 2 8 1 1
2 test 2 1 4 1
2 test 2 1 4 2
I need the results like this so that I can create sub-arrays in the php like this:
$articles = $query->result_array();
$output = array();
foreach ($articles as $article) {
// set up article details
$article_id = $article['id'];
// add article details
$output[$article_id]['article_id'] = $article_id;
$output[$article_id]['date_added'] = $article['date_added'];
$output[$article_id]['title'] = $article['title'];
$output[$article_id]['content'] = $article['content'];
// set up people details and add people array with details if exists
if (isset($article['person_id'])) {
$person_id = $article['person_id'];
$output[$article_id]['people'][$person_id]['person_id'] = $person_id;
$output[$article_id]['people'][$person_id]['lastname'] = $article['lastname'];
$output[$article_id]['people'][$person_id]['firstname'] = $article['firstname'];
}
// set up organizations details and add organizations array with details if exists
if (isset($article['organization_id'])) {
$organization_id = $article['organization_id'];
$output[$article_id]['organizations'][$organization_id]['organization_id'] = $organization_id;
$output[$article_id]['organizations'][$organization_id]['organization_name'] = $article['organization_name'];
}
// set up categories details and add categories array with details if exists
if (isset($article['category_id'])) {
$category_id = $article['category_id'];
$output[$article_id]['categories'][$category_id]['category_id'] = $category_id;
$output[$article_id]['categories'][$category_id]['category_name'] = $article['category_name'];
}
}
But if I just use LIMIT (with offset etc) 1
the results I get are
---------------------------------------------------------------------
id title category_id person_id organization_id
---------------------------------------------------------------------
1 test 1 1 1
instead of
---------------------------------------------------------------------
id title category_id person_id organization_id
---------------------------------------------------------------------
1 test 1 1 1
1 test 2 1 1
1 test 1 2 1
1 test 1 1 2
1 test 5 1 1
1 test 8 1 1
1 test 1 4 1
1 test 1 4 2
1 test 1 1 1
which is my desired result.
OK, so finally I worked out how it is possible.
Thought i'd include it here in case anyone else has the same problem.
Changing this line
FROM articles AS a
to this
FROM (SELECT * FROM articles LIMIT 5,3) AS a
does what I wanted.
So, why don't you use OFFSET 0,10 and LIMIT *number_of_results* in the SQL Query? (if I understood the question)
Specific number of IDs... WHERE ID IN (2,4,6,8)... ?
Are you using codeigniter's pagination?
http://codeigniter.com/user_guide/libraries/pagination.html
You can easily limit the number of records that are being returned using the MySQL LIMIT clause. This can be achieved like the following with your sample query.
SELECT a.id, date_added, title, content, category_id, person_id, organization_id, c.name AS category_name, firstname, lastname, o.name AS organization_name
FROM articles AS a
LEFT OUTER JOIN articles_categories AS ac ON a.id=ac.article_id LEFT OUTER JOIN categories AS c ON c.id=ac.category_id
LEFT OUTER JOIN articles_people AS ap ON a.id=ap.article_id LEFT OUTER JOIN people AS p ON p.id=ap.person_id
LEFT OUTER JOIN articles_organizations AS ao ON a.id=ao.article_id LEFT OUTER JOIN organizations AS o ON o.id=ao.organization_id
ORDER BY date_added
LIMIT 10
Where 10 is the number of records you wish to display. The MySQL LIMIT clause allows you to specify a limit of the number of records and an initial offset. Like so:
LIMIT <offset>,<limit>
In your case <offset> would be the current page * the number of records on a page. <limit> would be the number of records you would like to display per page.

PHP - SQL: fetching results in round robin fashion

I have a table, which consists of 3 fields:
id
name
status
Every time I get the results, it should give me 5 names whose status = 1.
Suppose the db contains following:
id name status
1 A 1
2 B 1
3 C 0
4 D 1
5 E 0
6 F 0
7 H 1
8 I 1
9 J 1
10 K 1
11 L 1
12 M 0
1st time, fetch should return: A,B,D,H,I (5 records)
2nd time, fetch should return: J,K,L,A,B (5 records)
UPDATE: I don't want typical pagenation. Consider I have 12 available names from A1 to A12. The first fetch should return A1-A5, second fetch A6-A10 and third fetch A11, A12, A1, A2, A3. So when I reach the end, I need to get records starting from the first to fill the 5 slots.
i am doing it in php with mysql
This looks like some sort of job allocation script?
You need 2 things:
the highest ID returned last time the script was run (lastID)
a number larger than the maximum ID in the table (bigNum)
Then you can write your query as
SELECT
id, name
FROM
table
WHERE
status=1
ORDER BY
(bignum + id) MOD (bigNum + lastID + 1)
LIMIT 5
Shazaam!
Keep track of the ids of the records returned, and for the following queries do:
select top 5 *
from (
select top 5 *
from MyTable
where status = 1
and id not in (1,2,4,7,8)
order by name
union
select top 5 *
from MyTable
where status = 1
order by name
) a
$q = mysql_query("SELECT name FROM table WHERE status = 1 LIMIT 5);
while ($row = mysql_fetch_row($q))
{
.... //first 5
}
$q = mysql_query("SELECT name FROM table WHERE status = 1 LIMIT 5,5);
while ($row = mysql_fetch_row($q))
{
.... //second 5
}
this uses the offset functionality of mysql- think of it as pagination for your results.

Categories