group records & get size of each group in rails - postgresql

Hi I have table called Sold Products which stores buying information for product & schema is as follows.
id |username | product_id| timestamp
I have another table product its schema is
id | product_name | description
I want to get most sold products. How to get that in active record?Please help.

Two ways of doing this... the first one being easier and more efficient than the second:
Method 1: Use a counter cache
class SoldProduct < ActiveRecord::Base
belongs_to :product, :counter_cache => true
end
Then you'd add a sold_products_count attribute to the Product table and find them using this:
Product.find(:all, :order => 'sold_products_count')
Method 2: Do it based on SQL
sales_count = Product.joins(:sold_products).count(:group=>"sold_products.product_id").sort_by{|product, sales| sales}.reverse
sales_count.each {|product, sales| puts "Product #{product} has #{sales} sales"}

Related

Repeat field based on quantity in Gravity Forms

Im trying to setup a form with Gravity forms that automatically populates the field "Name of person" based on a quantity field.
So lets say a user sets product quantity to 1:
Then the list field shows 1 row with Name | Last name | Date of birth
But when a users sets product quantity to 4 im trying to achieven that automatically 4 rows are displayed like:
Row 1.
Name | Last name | Date of birth
Row 2.
Name | Last name | Date of birth
Row 3.
Name | Last name | Date of birth
Row 4.
Name | Last name | Date of birth
Im really hoping somebody can help me out with this issue.
Im stuck.
Thanks in advance.
We have a free snippet for that here:
https://gravitywiz.com/set-number-of-list-field-rows-by-field-value/
For your setup, you'll want to target the Product's quantity input:
new GWAutoListFieldRows( array(
'form_id' => {FORM_ID},
'list_field_id' => {LIST_FIELD_ID},
'input_html_id' => '#input_{PRODUCT_FIELD_ID}_3'
) );```

Drools - Finding a single matching condition for a table of products ranked by consumers

I have a table displaying information for the top four ratings of produce in a store. I want to be able to find specific products in this rating table. Here is a structure of the table
----------------------------------------------------------------------------
sectId | product_code | product_category | consumer_raniking
10444 | 11222 | PRODUCE | RATING_1
10444 | 45555 | PRODUCE | RATING_1
10444 | 10005 | PR0DUCE | RATING_1
20555 | 11344 | PRODUCE | RATING_2
20555 | 94003 | PRODUCE | RATING_2
... and so on.
I wrote a rule to find inserted products which ins not working the way I want, i.e. to find the targetted fact that was inserted into the table. Here is the rule I put together:
rule "find by product codes rating_1"
when
$product_table: ProductRanking( $rank1: this.getProductCodesRankFirst())
$product1 : Product( this.product_code memberOf $rank1, $product_code: product_code )
$product2 : Product( this.product_code == 10444,this.product_code != $product_code ,$product_code2: product_code)
then
System.out.println("Found Products for product_codes "+$product_code+ " "+$product_code2 ) ;
end
Unfortunately, this returns 3 rows. I inserted into the session the product in row 2 i.e. product with ocde 45555 and it does find row 2. However, ir also brings in row 1 and row3.
I can see why it's doing that. It's because the skus are in the sectId with sectId 10444. However, I want to only bring in the row
that I inserted, which is sectionId(10444), product_code(45555). How can I achieve that?
I solved it by using a global to filter out the extra products. In the first line that brings the rankings, I eliminate the extra-matching products this way:
global ProductHelper productHelper
$product_table: ProductRanking( $rank1: productHelper.getProductCodesRankFirst(),
productCode != productHelper.getProductCodeFruitCategory() && productCode!=
productHelper.productCodeVegetableCategory())
The ProductHelper identifies the product codes I want to eliminate and hence the extra 2 products brought in are ignored, creating a single match. I'm sure there is a better way, but since I'm no expert, this is what I was able to come up with.

How to use ts_query with ANY(anyarray)

I currently have a query in PostgreSQL like:
SELECT
name
FROM
ingredients
WHERE
name = ANY({"string value",tomato,other})
My ingredients table is simply a list of names:
name
----------
jalapeno
tomatoes
avocados
lime
My issue is that plural values in the array will not match single values in the query. To solve this, I created a tsvector column on the table:
name | tokens
---------------+--------------
jalapeno | 'jalapeno':1
tomatoes | 'tomato':1
avocados | 'avocado':1
lime | 'lime':1
I'm able to correctly query single values from the table like this:
SELECT
name,
ts_rank_cd(tokens, plainto_tsquery('tomato'), 16) AS rank
FROM
ingredients
WHERE
tokens ## plainto_tsquery('tomato')
ORDER BY
rank DESC;
However, I need to query values from the entire array. The array is generated from another function, so I have control over the type of each of items in the array.
How can I use the ## operand with ANY(anyarray)?
That should be straight forward:
WHERE tokens ## ANY
(ARRAY[
plainto_tsquery('tomato'),
plainto_tsquery('celery'),
plainto_tsquery('vodka')
])

Postgresql query results to depend on few rows of same table

I'm working on some application, and we're using postgres as our DB. I don't a lot of experience with SQL at all, and now i encountered a problem, that i can't find answer to.
So here's a problem:
We have privacy settings stored in separate table, and accessibility of each row of data depends on few rows of this privacy table.
Basically structure of privacy table is:
entityId | entityType | privacyId | privacyType | allow | deletedAt
-------------------------------------------------------------------
5 | user | 6 | user | f | //example entry
5 | user | 1 | user_all | t |
In two words, this settings mean, that user id5 allows to have access to his data to everybody except user id6.
So i get available data by query like:
SELECT <some_relevant_fields> FROM <table>
JOIN <join>
WHERE
(privacy."privacyId"=6 AND privacy."privacyType"='user' AND privacy.allow=true)
OR (
(privacy."privacyType"='user_all' AND privacy."deletedAt" IS NOT NULL)
AND
(privacy."privacyType"='user' AND privacy."privacyId"=6 AND privacy.allow!=false)
);
I know that this query is incorrect in this form, but i want you to get idea of what i try to achieve.
So it must check for field with its type/id and allow=true, OR check that user_all is not deleted(deletedAt field is null) and there is no field restricting access with allow=false to this user.
But it seems like postgres is chaining all expressions, so it overrides privacy."privacyType"='user_all' with 'user' at the end of expression, and returns no results, or returns data even if user "blocked", because 'user_all' exist.
Is there a way to write WHERE clause to return result if AND expression is true for 2 different rows, for example in code above: (privacy."privacyType"='user_all' AND privacy."deletedAt" IS NOT NULL) is true for one row AND (privacy."privacyType"='user' AND privacy."privacyId"=6 AND privacy.allow!=false) is true for other, or maybe check for absence of row with this values.
Is this what you want?
select <some_fields> from <table> where
privacyType='user_all' AND deletedAt IS NOT NULL
union
select <some_fields> from <table> where
privacyType='user' AND privacyId=6 AND allow<>'f';
You left join the table with itself and found what element doesnt have a match using the where.
SELECT p1.*
FROM privacy p1
LEFT JOIN privacy p2
ON p1."entityId" = p2."entityId"
AND p1."privacyType" = 'user_all'
AND p1."deletedAt" IS NULL
AND p2."privacyType"='user' AND
AND p2."privacyId"= 6
AND p2.allow!=false
WHERE
p2.privacyId IS NOT NULL

Search data associated with changing username

In a hypothetical project I am working on there are users who can play games and set highscores, the users display name can change at any time but duplicates are not allowed. I plan on using MongoDB as it seems to support more rapid development than SQL alternatives. There are many types of games a user can play, all which have some kind of score which will need to be stored in the database. The scores will then need to be queried for their score so a high scores list can be built. Coming from SQL I could do something like this:
+------+-----------+
|UserID|DisplayName|
+------------------+
|883 |John02 |
|2321 |James55 |
|22 |Sam |
|943 |Joe |
+------+-----------+
+------+------+-----+
|GameID|UserID|Score|
+-------------------+
|1 |883 |9001 |
|3 |2321 |2 |
|2 |22 |1337 |
|2 |943 |998 |
+------+------+-----+
What is something equivalent for Mongo? Am I thinking of this too much like a relational database?
You need to have two collections namely Users , Games.
note: In mongodb, tables are called as collections. then, user id will be generated automatically in mongodb. you don't need specific field for user id.
where Games belongs to User. and User has_many Games. below is code snippet using ruby on rails.
class User
...
field :name
has_many :games
end
class Games
...
field :score
belongs_to :User
end
When you have this kind of architecture, you can query your database to get games associated with user like below
usr = User.where(name: "some name")
usr.games.all => return all games asssociated with particular user
any doubt, feel free to comment.
It all depends on kind of query you are going to frequently making . For example in case all your query is associated to user , like show all the game played by a user you can keep the schema like this, user collection will be have document like this , where Games is embedded sub document.
{
Id : "",
Name : "Test Name",
Games : [{ Id : 1 , Score : 1234 } , { Id : 2 , Score : 3456}]
}
But the problem with this schema is that now if you want to search for certain game top scorer it is going to be very tricky , but we can duplicate the data in another collection called Game
{
Id : 123,
Scores : [{ User : "Test" , Score : 5678} , { User : "Hello" , Score : 3456 }],Top Scorer : [{}]
}