count and group by using ExcecuteQuery - grails

how to get count number with group by activationDate?
i tried this query
def mapQuery6= new HashMap()
def query6 = "SELECT count(al.id) as totalCount,al.activationDate from Card al where and TO_DAYS(al.activationDate) > TO_DAYS(:from) and TO_DAYS(al.activationDate) <= TO_DAYS(:to) GROUP BY al.activationDate "
mapQuery6.from = params.from
def to = new Date().parse('dd/MM/yyyy HH:mm:ss', params.to+ " 05:00:00")
to.setDate(to.getDate() + 1)
mapQuery6.to = to
println "query 6 = "+query6
def activecard = Card.executeQuery(query6,mapQuery6)[0]
println "activecard = "+activecard
i want the result like this
if iam using Group by al.activationDate the the result when i printed was
activecard = [1, 2014-06-17 20:27:11.0]
and if without group by al.activationDate the result was
activecard = [6, 2014-06-27 20:27:11.0]
so i want ge a count number every month..
example 2014-07-xx have 3 count, 2014-06-xx 2, and 2014-05-xx only 1

Try grouping by month like
GROUP BY MONTH(al.activationDate)

Related

sum total column of a table

I have a this query in rails:
def self.nominas(params)
query = select("payroll_employees.*,payroll_employees.total, concat(e.name, ' ', e.surname, ' ', e.other_surname) as nombre_empleado, ec.code as contrato, CASE WHEN payroll_employees.is_wage_integral = TRUE THEN 'Si' WHEN payroll_employees.is_wage_integral = FALSE THEN 'No' END AS salario_es_integral, pc.integral_wage AS p_c_integral_wage")
query = query.joins("inner join payrolls p on (p.id = payroll_employees.payroll_id) inner join employee_contracts ec on (ec.id = payroll_employees.employee_contract_id) inner join employees e on (e.id = ec.employee_id) inner join payroll_companies pc on (pc.company_id = p.company_id) ")
query = query.where('p.id = :nomina', {nomina: params[:id] })
query = query.group(:id, 'e.name', 'e.surname', 'e.other_surname', 'ec.code', 'pc.integral_wage')
query = query.having("(lower(concat(e.name, ' ', e.surname, ' ', e.other_surname)) LIKE :campo_busqueda or :campo_busqueda = '') OR (lower(ec.code) LIKE :campo_busqueda or :campo_busqueda = '')", {campo_busqueda: "%#{params[:buscador].try(:downcase)}%"})
query = query.order('nombre_empleado')
end
in which I have a column "total", and I need to do the summation of the column "total" of all the records that the query brings me, my problem comes at the time of doing this:
#payroll_employees = PayrollEmployee.nominas(params)####
#sum_total = #payroll_employees.sum(:total)
it brings me something like this:
{[345, "Angel", "BONILLA", "MONTAÑO", "2010", true]=>0.106215575500000000000001e7, [079, "Bill f", "CABRERA", "RICO", "1846", true]=>0.1330346e7, ...
it seems to me that it is because my query has a group. Is it possible to do the summation and get a single number instead of a grouped array of totals?
Try to use sum function on total sum(payroll_employees.total)
def self.nominas(params)
query = select("payroll_employees.*,sum(payroll_employees.total) as total, concat(e.name, ' ', e.surname, ' ', e.other_surname) as nombre_empleado, ec.code as contrato, CASE WHEN payroll_employees.is_wage_integral = TRUE THEN 'Si' WHEN payroll_employees.is_wage_integral = FALSE THEN 'No' END AS salario_es_integral, pc.integral_wage AS p_c_integral_wage")
query = query.joins("inner join payrolls p on (p.id = payroll_employees.payroll_id) inner join employee_contracts ec on (ec.id = payroll_employees.employee_contract_id) inner join employees e on (e.id = ec.employee_id) inner join payroll_companies pc on (pc.company_id = p.company_id) ")
query = query.where('p.id = :nomina', {nomina: params[:id] })
query = query.group(:id, 'e.name', 'e.surname', 'e.other_surname', 'ec.code', 'pc.integral_wage')
query = query.having("(lower(concat(e.name, ' ', e.surname, ' ', e.other_surname)) LIKE :campo_busqueda or :campo_busqueda = '') OR (lower(ec.code) LIKE :campo_busqueda or :campo_busqueda = '')", {campo_busqueda: "%#{params[:buscador].try(:downcase)}%"})
query = query.order('nombre_empleado')
end

tweepy user_timeline with pagination returning max of 3200 tweets per twitter user

I'm using the code from here to scrape the tweets of a few users and export is as a .csv: https://towardsdatascience.com/tweepy-for-beginners-24baf21f2c25
I want to ideally get all the tweets of each user, but it seems to be limited to only the most recent 3200 tweets. Here's the exact code I'm using with trump as an example:
ids = ['realDonaldTrump']
def extract_hashtags(hashtag_list):
final_hashtag = ''
for hashtag in hashtag_list:
final_hashtag = final_hashtag + ' ' + hashtag['text']
return final_hashtag.strip()
#from https://towardsdatascience.com/tweepy-for-beginners-24baf21f2c25
class TweetMiner(object):
result_limit = 20
data = []
api = False
twitter_keys = { #redacted }
def __init__(self, keys_dict=twitter_keys, api=api, result_limit = 20):
self.twitter_keys = keys_dict
auth = tw.OAuthHandler(keys_dict['consumer_key'], keys_dict['consumer_secret'])
auth.set_access_token(keys_dict['access_token_key'], keys_dict['access_token_secret'])
self.api = tw.API(auth)
self.twitter_keys = keys_dict
self.result_limit = result_limit
def mine_user_tweets(self, user,
mine_rewteets=False,
max_pages=5):
data = []
last_tweet_id = False
page = 1
while page <= max_pages:
if last_tweet_id:
statuses = self.api.user_timeline(screen_name=user,
count=self.result_limit,
max_id=last_tweet_id - 1,
tweet_mode = 'extended',
include_retweets=True
)
else:
statuses = self.api.user_timeline(screen_name=user,
count=self.result_limit,
tweet_mode = 'extended',
include_retweets=True)
for item in statuses:
mined = {
'tweet_id': item.id,
'name': item.user.name,
'screen_name': item.user.screen_name,
'retweet_count': item.retweet_count,
'text': item.full_text,
'mined_at': datetime.datetime.now(),
'created_at': item.created_at,
#'time_zone': item._json['time_zone'],
'favourite_count': item.favorite_count,
'hashtags': extract_hashtags(item.entities['hashtags']),
#'links': extract_
'status_count': item.user.statuses_count,
'location': item.place,
'source_device': item.source
}
try:
mined['retweet_text'] = item.retweeted_status.full_text
except:
mined['retweet_text'] = 'None'
try:
mined['quote_text'] = item.quoted_status.full_text
mined['quote_screen_name'] = status.quoted_status.user.screen_name
except:
mined['quote_text'] = 'None'
mined['quote_screen_name'] = 'None'
last_tweet_id = item.id
data.append(mined)
page += 1
return data
#result_limit * max_pages is the no of tweets for each id
miner=TweetMiner(result_limit = 460) #200
counter = 0
counter2 = 0
for id in ids:
try:
print("Fetching tweets of " + id+ " now...")
mined_tweets = miner.mine_user_tweets(user= id, max_pages=460) #100
mined_tweets_df= pd.DataFrame(mined_tweets)
counter2 = counter2 +1
#after 40 tries, pause for 15 mins
if counter2%40==0: #5
print("Couldn't fetch, sleeping for 15 mins")
time.sleep(900) #15 minute sleep time
except:
print(id, 'is invalid or locked')
if counter>0:
final_df = pd.concat([final_df, mined_tweets_df], ignore_index = True)
print("Fetched and added!")
else:
final_df = mined_tweets_df
print("Fetched and added!")
counter +=1
print(final_df)
final_df.to_csv('tweets.csv', encoding='UTF-8')
The number of tweets returned should be 460*460 = 211,600 tweets for each user in ids, but it only returns a total of 3200 tweets per id. Is this limit a strict one built into the API, and if so, is there any way to get more than 3200 tweets per user?
This is a limit built into the Twitter API. The user timeline can only return a maximum of 3200 Tweets (in 200 Tweets per “page”). To retrieve more, you would need to use the premium or enterprise full archive search API.

Looping an array of tables

How can I loop this array of tables?
TASK_CONFIG = {
[1] = {NAME = "1-a", COUNT = 10, REWARD = 1000},
[2] = {NAME = "4-b", COUNT = 10, REWARD = 6000},
[3] = {NAME = "3-a", COUNT = 15, REWARD = 2400},
}
I need something like:
for each ITEM in TASK_CONFIG
for each FIELD in ITEM
-- do something
next
next
The idea is looping every field, for example:
Looping every row and getting the values "name", "count", "reward"
for a, b in pairs(TASK_CONFIG) do
for c, d in pairs(b) do
-- print info / do something
end
end

Tarantool: limit/offset in index.indexName:pairs call

I need to fetch some records from space users.
This space has a secondary index category_status_rating.
I need select users with category=1, status=1, rating<=123456789:
for _, user in box.space.users.index.category_status_rating:pairs({ 1, 1, 123456789 }, { limit = 20, offset = 5, iterator = box.index.LE }) do
if user[categoryIdx] ~= 1 or user[statusIdx] ~= 1 then break end
table.insert(users, user)
end
As I know, iteration with indexName:pairs does not support limit and I can just user my own counter. But what about offset? Can I use this param and start from "page" I need? Or will I iterate without any offset and pass useless records (about 100000) and start to table.insert(users, user) when my "page" starts?
Thanks!
Instead of using offset, you can save your position (that will be last checked tuple) if you really need it.
e.g:
local last = 123456789
for i = 1, 2 do
local count = 0
for _, user in box.space.users.index.category_status_rating:pairs({1, 1, last}, { iterator = box.index.LE }) do
if user[categoryIdx] ~= 1 or user[statusIdx] ~= 1 or count > 20 then
break
end
table.insert(users, user)
last = user[LAST_INDEX_FIELD]
count = count + 1
end
-- process your tuples
end
or, using luafun (where drop_n is analog of limit, and saving into last is analog of offset):
local last = 123456789
for i = 1, 2 do
local users = box.space.users.index.category_status_rating:pairs({1, 1, last}, { iterator = box.index.LE }):take_n(20):map(function(user)
last = user[LAST_INDEX_FIELD]
return user
end):totable()
-- process your tuples
end
Documentation on LuaFun, which is embedded into Tarantool.

Order/randomize/convert array in rails

I've got this:
a = [[123,1],[124,1],[125,1],[126,2],[127,3],[128,3]]
And I would like to turn a into b:
ordered by value
random within array of value
// updated:
b = [[124,123,125],[126],[128,127]]
How to do this in ruby? Im using rails.
a.group_by(&:last).
sort_by(&:first).
map(&:last).
map {|el| el.map(&:first).shuffle }
One solution is:
a = [[123,1],[124,1],[125,1],[126,2],[127,3],[128,3]]
a = a.sort {|d, e| d[1] <=> e[1]}
prev = a[0][1]; result = []; group = [];
a.each do |e|
if e[1] == prev
group << e[0]
else
result << group.shuffle
group = [e[0]]
prev = e[1]
end
end
result << group
p result
run:
$ ruby t.rb
[[125, 123, 124], [126], [127, 128]]
a.reduce([]){|m,i|m[i[1]]=(m[i[1]]||[])<<i[0];m}.compact

Resources