How to generate increment number for each group of data? [duplicate] - php

This question already has an answer here:
Ranking the results in mysql (mysql equivalents for 'dense_rank()' or 'row_number()' functions in oracle)
(1 answer)
Closed 4 years ago.
This is my table data
prod_id category_id
1 1
2 2
3 2
4 3
5 3
6 3
Expected result
prod_id category_id seq_no
1 1 1
2 2 1
3 2 2
4 3 1
5 3 2
6 3 3
This is just one of the sample to generate sequence number based on category, it might be other condition as well.
I am trying to generate sequence number for each group of data i get based on id_category field. I tried dense_rank() method but it is not supported for MySQL.
How can i generate sequence number for each group in this way?
DENSE_RANK() OVER (ORDER BY id_category) As seq_no
My query
Product::leftJoin('category','category.id_category','=','product.id_category')
........
->get();

If you don't have huge amounts of data, it's probably easiest to
grab everything
group by category
sort each category by product
loop through each category and set the sequence number based on the current index
While I don't know the exact nature of your tables, it would look something like this, with your query as the start:
Product::leftJoin('category','category.id_category','=','product.id_category')
->get()
->groupBy('category_id')
->each(function ($group) {
$group->sortBy('product_id')
->map(function ($product, $index) {
$product->seq_no = $index + 1;
});
});
Though note that this should be treated as pseudocode and adapted as fits your application best.

Related

Laravel select random rows from table based on another field

There is a words table with 20000 records:
ID name rank
1 word1 3
2 word2 5019
3 word3 12334
4 word4 23
5 word5 544
I want to select 400 words randomly from this table but with this condition :
first 20 words: select 20 words randomly from words with rank between 1 and 1000
second 20 words: select 20 words randomly from words with rank between 1000 and 2000
And so on...
Do I have to do this in 20 separate queries? How? Is there a better way?
I am using laravel 5.4 and Mysql, Also a raw query suggestion would be appreciated. Thank you
Easy way
use a where clause to filter their rank, then use inRandomOrder() and take(20) to get 20 random ones.
Word::inRandomOrder()->where('rank', '>=', 1)->where('rank', '<=', 1000)->take(20);
Hard way
To get them all in one query, you might try some funky logic like this:
first: define a view that returns the same table, but instead of rank, has categories, so category 1 for 1<=rank<1000, .... just to make the next step easier
now we can use partition by (see Trying to understand over() and partition by). Remember to order by RAND() inside the partition. Order the result of all this by rownumber.
Now we have a result that looks like this:
rownumber name category
1 word1 1
1 word2 2
1 word3 3
1 word4 4
...
2 word21 1
2 word22 2
2 word23 3
2 word24 4
...
20 word381 1
20 word382 2
20 word383 3
20 word384 4
...
By taking 400 of these tuples, we will have 20 random samples of each of the 20 categories.
Note-- ordering by RAND() can be slow, as explained here http://www.titov.net/2005/09/21/do-not-use-order-by-rand-or-how-to-get-random-rows-from-table/
Edit: turn out partition by is for sql server only. But you could do something similar in mysql

MySQLi- How to get number of records in one table that do not match values in another table [duplicate]

This question already has answers here:
How to Find Missing Value Between Two Mysql Tables
(4 answers)
Closed 7 years ago.
Sorry for the obscure title... I don't know how best to explain this.
I have two tables, valid_sizes and items
valid_sizes:
ID SizeID Description
1 40 Small
2 41 Medium
3 42 Large
items:
ID Size
1 41
2 41
3 40
4 99
5 42
6 98
I am attempting to perform a query that finds how many items exist whose size does not exist in the valid_sizes table. In this instance, a query that would return 2. (Items 4 and 6 do not exist as a SizeID)
How would this be done?
Something like this should work. You want to do a left join, and check for NULL results.
SELECT * FROM items
LEFT JOIN valid_sizes ON items.SizeID = valid_sizes.Size
WHERE
Size IS NULL;

Mysql return only items that have n number of property matches

I have a database of items and each item has various number of properties. Is it possible for MySql only to return items that have a certain number of matches (not properties) when a search is run?
Example: I am searching for any item with a wheel that is red and has a tire.
This would return all items with these three matches even if they have more properties and would automatically exclude anything that has less than 3 matches.
I have tried playing with the COUNT + GROUP BY + HAVING but I was unable to put together a meaningful working code. Before I spend more time on this I would like to know if it is possible at all.
TABLE DESIGN
ID ITEM PROPERTY
1 1 red
2 1 wheel
3 1 tire
4 2 red
5 2 wheel
6 2 tire
7 2 lamp
8 3 red
9 3 wheel
10 4 red
I would like it to return ITEM 1 and 2
You would do this with a group by and having. You really provide no information about your data structure, but the basic idea is:
select ip.item
from design ip
where ip.property in ('wheel', 'red', 'tire')
group by ip.item
having count(distinct ip.property) = 3;

Lowest free value in mysql column

I already searched but I always find LEAST and GREATEST as hints. I want to have the next ascending number in a row that's not used. Like the following:
entries
1
2
3
5
6
7
If every of the numbers is for one row in my table I want the number 4 as a result and in the following example:
1
2
3
4
5
6
I want the number 7 as a result. Is there any possiblity to accomplish this in an SQL statement?
Best,
Robin
This query assumes that the number 1 is in your table
select min(number) + 1 from entries e1
where not exists (
select 1 from entries e2
where e2.number = e1.number + 1
)
If you want all missing numbers (where gaps are no larger than 1) instead of the smallest one, then remove min()
It think the solution is to do a self-join with the next value, and extract the first lowest result. Example:
Table: values, with column value
SELECT v1.value
FROM values v1
LEFT JOIN values v2 ON v1.value = (v2.value + 1)
WHERE v2.value IS NULL
ORDER BY v1.value ASC
LIMIT 1

Detecting columns in a document (table) via php - Algorithm

Given a table like the one below, what would be the best way to detect the two columns separately?
So what I would need the total colspans for the first column.
What is important to remember is that the nr of columns can change.
In the case of this example, the second column starts at "10 euro" (second row). The first section is equal to 2 colspans. The other section is 5 colspans.
Any (abstract) ideas on how to do this?
You must consider the gaps in between the table cells and mark their positions, like this::
0 1 2 3 4 7
0 2 3 4 5 6 7
0 1 2 4 5 7
...
0 2 7
Once you have built an array with above information, you iterate over them and mark the common gap locations:
0 2 7
Since 0 and 7 are both at the edges of your table, you can strip those off. Then you're left with position 2 as the common gap between your rows.
Done :)

Categories