SQL Query in Rails - ruby-on-rails

I have table with 3 columns : tableno,itmname, itmtype. The itmtype can be red or blue only. This table may have rows like: table01,item1,red ; table01,item2,blue; table02,item1,blue; table02,item4,red; table03,item1,red; table03,item5,red.
Now I need to extract tableno for which all itmtypes is red. So from above rows I need output as table03 as itmtype is red for both items in it. Normally if I put where condition for itmtype as red, it may fetch table01 & table02 as well coz both has one item with itmtype red. But I need only table03 as my output coz all itmtype is red for this table.
I am struggling for quite long time writing different types of queries in rails but none of them is working.
I have written a sql query for that unable to write a similar one in rails.
select tableno,itmstatus,count(itmstatus) from lists l1 group by l1.tableno,itmstatus
having itmstatus = 'red' and count(itmstatus) = (select count(itmstatus) from lists l2 where l1.tableno = l2.tableno group by tableno)
Since I am unable to convert this in rails, couldn't test on rails console to check if it will work. I understand that this may sound a basic question but being new to rails I have only used normal select only. Please advise. Thanks.

if you have correct sql syntax then put it in a string and use the find_by_sql method
like
Model.find_by_sql("your query")
please check the links
http://apidock.com/rails/ActiveRecord/Base/find_by_sql/class
find_by_sql with array format in Rails 3

Related

SELECT statement with multiple conditions on TAGs

For considerably long period of time I’ve been struggling the following problem. This is an example of data stored in the DB:
> show series
flights,cycleId=1535,cycleIdx=0,engineId=2,flightId=1696,flightIdx=0,type=fil
flights,cycleId=1535,cycleIdx=0,engineId=2,flightId=1696,flightIdx=0,type=std
flights,cycleId=1535,cycleIdx=0,engineId=2,flightId=1696,flightIdx=0,type=raw
...
and my intention is to select a specific one by using a query like this:
SELECT * FROM flights WHERE type='fil' AND engineId= '2' AND flightId = '1696' AND flightIdx = '0' AND cycleId = '1535' AND cycleIdx = '0'
Such query, however, yields always zero results. Zilch.
Selecting the first (and only) tag works fine:
SELECT * FROM flights WHERE cycleId = '1535'
but using this condition on any other tag, like for example
SELECT * FROM flights WHERE type='fil'
does never return a single row. Querying only the first tag and nothing else works.
Could you please give me a hint what am I doing wrong? From all I have found people are always selecting just by a single tag but never more. What is the part that I cannot see?
Many thanks for any ideas!
I believe I have discovered the reason: two keys from the tags made by mistake their way into the fields. I spotted the trouble when listing the tag and fields keys as
show tag keys
show field keys
Deleting all records does not remove the keys from these lists and the problem persists. One need to drop the entire database to restore the order of things.

Combining distinct with another condition

I'm migrating a Rails 3.2 app to Rails 5.1 (not before time) and I've hit a problem with a where query.
The code that works on Rails 3.2 looks like this,
sales = SalesActivity.select('DISTINCT batch_id').where('salesperson_id = ?', sales_id)
sales.find_each(batch_size: 2000) do |batchToProcess|
.....
When I run this code under Rails 5.1, it appears to cause the following error when it attempts the for_each,
ArgumentError (Primary key not included in the custom select clause):
I want to end up with an array(?) of unique batch_ids for the given salesperson_id that I can then traverse, as was working with Rails 3.2.
For reasons I don't understand, it looks like I might need to include the whole record to traverse through (my thinking being that I need to include the Primary key)?
I'm trying to rephrase the 'where', and have tried the following,
sales = SalesActivity.where(salesperson_id: sales_id).select(:batch_id).distinct
However, the combined ActiveRecordQuery applies the DISTINCT to both the salesperson_id AND the batch_id - that's #FAIL1
Also, because I'm still using a select (to let distinct know which column I want to be 'distinct') it also still only selects the batch_id column of course, which I am trying to avoid - that's #FAIL2
How can I efficiently pull all unique batch_id records for a given salesperson_id, so I can then for_each them?
Thanks!
How about:
SalesActivity.where(salesperson_id: sales_id).pluck('DISTINCT batch_id')
May need to change up the ordering of where and pluck, but pluck should return an array of the batch_ids

Ruby-on-Rails: Selecting distinct values from the model

The docs:
http://guides.rubyonrails.org/active_record_querying.html#selecting-specific-fields
Clearly state that:
query = Client.select(:name).distinct
# => Returns unique names
However, when I try that in my controller, I get the following error:
undefined method `distinct' for #<ActiveRecord::Relation:0xb2f6f2cc>
To be clear, I want the distinct names, like ['George', 'Brandon'], not the clients actual records. Is there something that I am missing?
The .distinct option was added for rails 4 which is what the latest guides refer to.
Rails 2
If you are still on rails 2 you will need to use:
Client.select('distinct(name)')
Rails 3
If you are on Rails 3 you will need to use:
Client.select(:name).uniq
If you look at the equivalent section of the rails 3 guide you can see the difference between the two versions.
There are some approaches:
Rails way:
Model.select(:name).distinct
Semi-rails way
Model.select("DISTINCT ON(models.name) models.*")
The second allows you to select the first record uniqued by name, but in the whole matter, not only names.
If you do not want ActiveRecord::Relations returned, just an array of the names as strings, then use:
Client.distinct.pluck(:name)
To get an ordered result set:
Client.order(:name).distinct.pluck(:name)
This will work for Rails 2 (pretty old rails I know!), 3 and 4.
Client.select('distinct(name)')
This will actually use the SQL select distinct statement
SELECT distinct name FROM clients

Fusion tables query does not fetch some

I'm having an issue on this table: 1g_ydg74ooUSBzNfQBHOIdgrOKhxZD_92In8xTDg
I'm trying to fetch some results by CODE_DEPT. I used the filter
CODE_DEPT IN ('001', '002', '003', '02A', '02B')
and only the 3 first are fetched.
Any idea what's going on ?
Cheers
Looks like CODE_DEPT is identified as a numeric column. The last two codes are not numeric and so would not match anything. If you change the column to type Text and you should be OK.

Return every nth row from database using ActiveRecord in rails

Ruby 1.9.2 / rails 3.1 / deploy onto heroku --> posgresql
Hi, Once a number of rows relating to an object goes over a certain amount, I wish to pull back every nth row instead. It's simply because the rows are used (in part) to display data for graphing, so once the number of rows returned goes above say 20, it's good to return every second one, and so forth.
This question seemed to point in the right direction:
ActiveRecord Find - Skipping Records or Getting Every Nth Record
Doing a mod on row number makes sense, but using basically:
#widgetstats = self.widgetstats.find(:all,:conditions => 'MOD(ROW_NUMBER(),3) = 0 ')
doesn't work, it returns an error:
PGError: ERROR: window function call requires an OVER clause
And any attempt to solve that with e.g. basing my OVER clause syntax on things I see in the answer on this question:
Row numbering in PostgreSQL
ends in syntax errors and I can't get a result.
Am I missing a more obvious way of efficiently returning every nth task or if I'm on the right track any pointers on the way to go? Obviously returning all the data and fixing it in rails afterwards is possible, but terribly inefficient.
Thank you!
I think you are looking for a query like this one:
SELECT * FROM (SELECT widgetstats.*, row_number() OVER () AS rownum FROM widgetstats ORDER BY id) stats WHERE mod(rownum,3) = 0
This is difficult to build using ActiveRecord, so you might be forced to do something like:
#widgetstats = self.widgetstats.find_by_sql(
%{
SELECT * FROM
(
SELECT widgetstats.*, row_number() OVER () AS rownum FROM widgetstats ORDER BY id
) AS stats
WHERE mod(rownum,3) = 0
}
)
You'll obviously want to change the ordering used and add any WHERE clauses or other modifications to suit your needs.
Were I to solve this, I would either just write the SQL myself, like the SQL that you linked to. You can do this with
my_model.connection.execute('...')
or just get the id numbers and find by id
ids = (1..30).step(2)
my_model.where(id => ids)

Resources