I am using the below query function but getting an error can anyone help
=QUERY($Q$1:$AD$1,
"SELECT A,COUNT(A)
WHERE A IS NOT NULL
GROUP BY A
PIVOT BY C")
Error -
Unable to parse query string for Function QUERY parameter 2: PARSE_ERROR: Encountered " "by" "BY "" at line 4, column 7. Was expecting one of: "true" ... "false" ... "date" ... "timeofday" ... "datetime" ... "timestamp" ... "min" ... "max" ... "avg" ... "count" ... "sum" ... "no_values" ... "no_format" ... "is" ... "null" ... "year" ... "month" ... "day" ... "hour" ... "minute" ... "second" ... "millisecond" ... "with" ... "contains" ... "starts" ... "ends" ... "matches" ... "like" ... "now" ... "dateDiff" ... "quarter" ... "lower" ... "upper" ... "dayOfWeek" ... "toDate" ... ... <INTEGER_LITERAL> ... <DECIMAL_LITERAL> ... <STRING_LITERAL> ... <QUOTED_ID> ... "(" ... "-" ... "min" ... "max" ... "count" ... "avg" ... "sum" ... "year" ... "month" ... "day" ... "hour" ... "minute" ... "second" ... "millisecond" ... "now" ... "dateDiff" ... "lower" ... "upper" ... "quarter" ... "dayOfWeek" ... "toDate" ... "(" ... <STRING_LITERAL> ... <DECIMAL_LITERAL> ... <INTEGER_LITERAL> ... "-" ... "true" ... "false" ... "date" ... "timeofday" ... "datetime" ... "timestamp" ... ... <QUOTED_ID> ... "min" ... "max" ... "avg" ... "count" ... "sum" ... "no_values" ... "no_format" ... "is" ... "null" ... "year" ... "month" ... "day" ... "hour" ... "minute" ... "second" ... "millisecond" ... "with" ... "contains" ... "starts" ... "ends" ... "matches" ... "like" ... "now" ... "dateDiff" ... "quarter" ... "lower" ... "upper" ... "dayOfWeek" ... "toDate" ...
Take out the "BY" after PIVOT. Also, columns A and C aren't in your range so you probably mean Q and S:
=QUERY($Q$1:$AD$1, "SELECT Q,COUNT(Q) WHERE Q IS NOT NULL GROUP BY Q PIVOT S")
You also have the option of making the range into an array by putting curly brackets round it, then using Col1 and Col3:
=QUERY({$Q$1:$AD$1}, "SELECT Col1,COUNT(Col1) WHERE Col1 IS NOT NULL GROUP BY Col1 PIVOT Col3")
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
Suppose I have these records, where r_years could have any number of year keys:
Item.select('id','name','r_years').where(name:"N1")
...
"id" => 1, "name" => "N1", "r_years" => {"year2020" => "1","year2021" => "2", ...}
"id" => 2, "name" => "N1", "r_years" => {"year2020" => "2","year2021" => "3", ...}
...
How can I get the sum of the r_years values, for every year key, like this:
#r_years_sum = {"year2020" => "3","year2021" => "5", ...}
You can map your result to get only the r_years values, and then use reduce and merge every value for each year and sum their value as an integer:
items.map do |item|
item['r_years']
end.reduce do |acc, item|
item.merge(acc) { |_, oldval, newval| (oldval.to_i + newval.to_i).to_s }
end
# {"year2020"=>"3", "year2021"=>"5"}
arr = [
{ "id"=>"1", "r_years"=>{ "2020"=>"1", "2021"=> "2", "2022"=>"3" } },
{ "id"=>"2", "r_years"=>{ "2020"=>"4", "2021"=> "5", "2022"=>"6" } },
{ "id"=>"3", "r_years"=>{ "2020"=>"7", "2021"=> "8", "2022"=>"9" } }
]
arr.each_with_object(Hash.new(0)) do |g,h|
g["r_years"].each { |k,v| h[k] += v.to_i }
end.transform_values(&:to_s)
#=> {"2020"=>"12", "2021"=>"15", "2022"=>"18"}
The first step is:
arr.each_with_object(Hash.new(0)) do |g,h|
g["r_years"].each { |k,v| h[k] += v.to_i }
end
#=> {"2020"=>12, "2021"=>15, "2022"=>18}
Hash#transform_values is then used to convert the values to strings.
This uses the second form of Hash::new, which takes an argument that is referred to as the default value. h[c] += 1 expands to h[c] = h[c] + 1. If h does not have a key c, h[c] on the right of the equality returns the default value of zero, yielding h[c] = 0 + 1.
You can try this ...
arr = [
{ "id"=>"1", "r_years"=>{ "2020"=>"1", "2021"=> "2", "2022"=>"3" } },
{ "id"=>"2", "r_years"=>{ "2020"=>"4", "2021"=> "5", "2022"=>"6" } },
{ "id"=>"3", "r_years"=>{ "2020"=>"7", "2021"=> "8", "2022"=>"9" } }
]
res_hash=Hash.new(0)
arr.each do |x|
x["r_years"].select{ |key,value| res_hash[key]+=value.to_i }
end
Given a an array of hashes where every hash is like {"date":"date_value", "slots":[slots_value]}, I'd like to gather hashes with the same dates on one hash and merge slots arrays.
Example input:
[{"date" : "2016/23/12", "slots" : ["a","b"]},
{"date" : "2016/23/12", "slots" : ["c","d","e"]},
{"date" : "2016/24/12", "slots" : ["x"]}
]
Example output:
[{"date" : "2016/23/12", "slots" : ["a","b","c","d","e"]},
{"date" : "2016/24/12", "slots" : ["x"]}
]
Enumerable#group_by is a very powerful tool for Hashes and Arrays :
input = [
{"date" => "2016/23/12" , "slots" => ["a","b"]},
{"date" => "2016/23/12", "slots" => ["c","d","e"]},
{"date" => "2016/24/12", "slots" => ["x"]}
]
puts input.group_by{|h| h["date"]}.map{|date, hashes|
{
"date" => date,
"slots" => hashes.map{|h| h["slots"]}.flatten
}
}
#=> {"date"=>"2016/23/12", "slots"=>["a", "b", "c", "d", "e"]}
# {"date"=>"2016/24/12", "slots"=>["x"]}
I am trying to call the uniq method on the follow json so that it would only return unique result base on employee_id
# Json array
a ={
results: [
{
employee: {
name: "A",
employee_id: "A-00016",
title: 1
}
},{
employee: {
name: "A",
employee_id: "A-00016",
title: 2
}
},{
employee: {
name: "C",
employee_id: "C-00017",
title: 3
}
}
]
}
# Calling uniq on a
a.uniq { |p| p.values_at(:employee_id) }
However, I am only getting this result
{
results: [
{
employee: {
name: "A",
employee_id: "A-00016",
title: 1
}
}
]
}
Instead of what I want
{
results: [
{
employee: {
name: "A",
employee_id: "A-00016",
title: 1
},{
employee: {
name: "C",
employee_id: "C-00017",
title: 3
}
}
]
}
Am I using the correct method to output the result I want?
With uniq:
input[:results].uniq { |e| e[:employee][:employee_id] }
#⇒ [
# {:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>"1"}},
# {:employee=>{:name=>"C", :employee_id=>"C-00017", :title=>"3"}}]
But I believe there should be some condition applied on what to choose from siblings having the same id. The code below selects the one, having max title value:
input[:results].group_by { |e| e[:employee][:employee_id] }
.map { |_, v| v.max_by { |e| e[:employee][:title].to_i } }
#⇒ [
# {:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>"2"}},
# {:employee=>{:name=>"C", :employee_id=>"C-00017", :title=>"3"}}]
Here is one way to do this, in order to return the modified input hash, we can use uniq! which will modify the array a[:results] in place. We use dup to duplicate the hash a to preserve it, and then use tap to operate on duplicated hash.
r = a.dup.tap do |h|
h[:results].uniq! do |h|
h[:employee][:employee_id]
end
end
#=> {:results=>
# [
# {:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>1}},
# {:employee=>{:name=>"C", :employee_id=>"C-00017", :title=>3}}
# ]
# }
def selection_criterion(h)
h[:title].to_i
end
{results: a[:results].group_by {|h| h[:employee][:employee_id]}.
values.
map {|arr| arr.max_by {|h| selection_criterion(h[:employee])}}}
#=> {:results=>
# [{:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>2}},
# {:employee=>{:name=>"C", :employee_id=>"C-00017", :title=>3}}]}
Define selection_criterion as desired, and possible change max_by to min_by.
The steps are as follows.
b = a[:results]
# => [{:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>1}},
# {:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>2}},
# {:employee=>{:name=>"C", :employee_id=>"C-00017", :title=>3}}]
c = b.group_by { |h| h[:employee][:employee_id] }
#=> {"A-00016"=>[{:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>1}},
# {:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>2}}],
# "C-00017"=>[{:employee=>{:name=>"C", :employee_id=>"C-00017", :title=>3}}]}
d = c.values
#=> [[{:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>1}},
# {:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>2}}],
# [{:employee=>{:name=>"C", :employee_id=>"C-00017", :title=>3}}]]
e = d.map { |arr| arr.max_by { |h| selection_criterion(h[:employee]) } }
#=> [{:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>2}},
# {:employee=>{:name=>"C", :employee_id=>"C-00017", :title=>3}}]
{ results: e }
#=> {:results=>
# [{:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>2}},
# {:employee=>{:name=>"C", :employee_id=>"C-00017", :title=>3}}]}
i have a rails app where i have some problems with indexes. I search locations by name.
First i thought its a problem with the addresses.coords but iam not sure about it.
The relevant parts of the search controller:
#practices = Practice.published
#practices = #practices.where(:"addresses.country" => params[:country].upcase) if params[:country].present?
if params[:location].present? && latlng = get_coordinates
#practices = #practices.near_sphere(:"addresses.coords" => latlng).max_distance(:"addresses.coords" => get_distance )
end
# now find doctors based on resulting practices
#doctors = Doctor.published.in("organization_relations.practice_id" => #practices.distinct(:_id))
The complete crash log:
Moped::Errors::OperationFailure (The operation: #<Moped::Protocol::Command
#length=255
#request_id=646
#response_to=0
#op_code=2004
#flags=[]
#full_collection_name="um-contacts.$cmd"
#skip=0
#limit=-1
#selector={:distinct=>"practices", :key=>"_id", :query=>{"deleted_at"=>nil, "published_at"=>{"$lte"=>2012-11-05 15:17:14 UTC}, "addresses.country"=>"DE", "addresses.coords"=>{"$nearSphere"=>[13.4060912, 52.519171], "$maxDistance"=>0.01569612305760477}}}
#fields=nil>
failed with error 13038: "exception: can't find special index: 2d for: { deleted_at: null, published_at: { $lte: new Date(1352128634313) }, addresses.country: \"DE\", addresses.coords: { $nearSphere: [ 13.4060912, 52.519171 ], $maxDistance: 0.01569612305760477 } }"
See https://github.com/mongodb/mongo/blob/master/docs/errors.md
for details about this error.):
app/controllers/search_controller.rb:16:in `index'
Thats the result of the indexes, not sure how to query them from the addresses which are embedded via has_many.
> db.practices.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "um-contacts.practices",
"name" : "_id_"
}
]
Help would be really appreciated!
Edit: Looks like the indexes for adresses.coords arent created,
db.system.indexes.find()
{ "v" : 1, "key" : { "_id" : 1 }, "ns" : "um-contacts.users", "name" : "_id_" }
{ "v" : 1, "key" : { "_id" : 1 }, "ns" : "um-contacts.doctors", "name" : "_id_" }
{ "v" : 1, "key" : { "_id" : 1 }, "ns" : "um-contacts.collaborations", "name" : "_i
{ "v" : 1, "key" : { "_id" : 1 }, "ns" : "um-contacts.practices", "name" : "_id_" }
but should be created within the practice class:
class Practice
...
embeds_many :addresses, cascade_callbacks: true, as: :addressable
...
field :name, type: String
field :kind, type: String
field :slug, type: String
index({"addresses.coords" => '2d'}, { min: -180, max: 180, background: true })
index({name: 1})
index({slug: 1}, { unique: true })
...
Anyone have an idea why its failing?
try to re-create your indexes. for mongoid:
rake db:mongoid:create_indexes
I have many coordinates embedded in place. How to get only first "start" coordinate for each self Place object? Scope is correct idea? I can select only first, last or all of the places with all(is very slow) coordinates, my commented out scope doesn't work.
code:
class Place
include Mongoid::Document
field :title, :type => String
embeds_many :coordinates
# def self.start_coordinate
# self.coordinates.first
# first = self.coordinates.first
## first = self.find({}, { "coordinates" => { "_id" => firstobj?}})
## first = self.find({}, { "coordinates" => {}, :limit=>1})
## self.includes(:coordinates).first
## self.collection.(:coordinates).find_one()
### self.all
# end
end
class Coordinate
include Mongoid::Document
include Mongoid::Spacial::Document
field :coordinates, :type => Array, spacial: true
spacial_index :coordinates
embedded_in :place, :inverse_of => :coordinate
end
MongoDB place object:
{ "_id" : ObjectId( "4ece5a04ca6a175b08000016" ),
"coordinates" : [
{ "lat" : 51.54983275438141,
"lng" : 17.31981750561522,
"_id" : ObjectId( "4ece5a04ca6a175b08000002" ) },
{ "lat" : 51.55282151156834,
"lng" : 17.35552307202147,
"_id" : ObjectId( "4ece5a04ca6a175b08000003" ) },
{ "lat" : 51.53830285151265,
"lng" : 17.39397522045897,
"_id" : ObjectId( "4ece5a04ca6a175b08000004" ) } ],
"created_at" : Date( 1322146308000 ),
"description" : "description",
"title" : "test",
"updated_at" : Date( 1322154405000 ),
"user_id" : ObjectId( "4ecd7d4eca6a175783000010" ) }
Scopes are typically used to filter the result set of whole objects you want based upon some criteria. Instead, it looks like you are trying to select certain attributes of a given document. To do that you should use the only method.
This might work, not sure about the exact syntax though:
Place.only(":coordinates.0")