Laravel: Get number of occurrences in table - php

I have this query in Laravel:
Models::select('*')->group_by('user_name')->order_by(DB::raw('count(user_name)'), 'desc')->take(3)->get();
It returns top 3 users by the number they appear in the table.
Q: How can I also get the count parameter(how many times they appear?)
Current response:
array(
"Tim","John","Luke"
);
I need something like this:
array(
array(
"user" => "Tim",
"count" => 3
),
array(
"user" => "John",
"count" => 2
),
array(
"user" => "Luke",
"count" => 1
)
);
Thanks!

You should do the COUNT in the select part of the query and alias it, then use that alias in the ordering.
Something like this, perhaps.
Models::select('*', DB::raw('count(user_name) AS user_count'))->group_by('user_name')->order_by(DB::raw('user_count'), 'desc')->take(3)->get();

Related

MongoDb + PHP: Cannot specify more than one positional proj. per query

I have a "users" collection containing 2 arrays of objects (cards and prizes) each of these 2 can contain data from different companies marked with the "id_company" field.
$list = $users->find(
array(
'cards.id_company' => '... id company ...',
'cards.is_active' => true,
),
array(
'projection' => array(
'_id' => 1,
'full_name' => 1,
'cards.$.id_company' => '...id company...',
'prizes.$.id_company' => '...id company...',
),
'limit' => 5,
)
);
I'm trying to select only the data relating to one company, consequently excluding the others, but I get the following error: Cannot specify more than one positional proj. per query.
Any solutions?

How to write a custom query in dynamodb using php?

In my case I have a table name "friends" which has two attributes:
account_id
fb_id
I try to get all the account_id based on fb_id, and for this wrote the query as below:
$response = $dynamoClient->getItem ( array(
"TableName" => "facebook_friendlist",
"ConsistentRead" => true,
"Key" => array(
"fb_id" => array(
"S" => "171092723281123"//$fbId
)
),
"ProjectionExpression" => "account_id"
) );
But its not getting executed. I also tried to write the same query using getItem(),scan(),getIterator() but no result.
Help me out with the right way. Thanks in advance.

Laravel 5.2 Eloquent column name conflict

I have the following method in my user class:
/**
* Get all organisations for user (if owner)
*
* #param
*/
public function getOrganisationsOwned()
{
// If the user is owner of any one or many organisations then return this list
return Organisation::leftJoin('subscription_plans', 'organisations.subscription_plan_id', '=', 'subscription_plans.id')
->where('organisations.owner_id', '=', $this->id)
->select('organisations.*', 'subscription_plans.*')
->get();
}
The method essentially queries and joins two tables. Each table has a column called title.
The output from the above generates the rows as desired with the right info, but returns only one title column, from the right table (subscription_plans) but not the column title from the left table (organisations). I also notice it is dropping the timestamps from one table also, as these are of the same column name.
I understood that
->select('organisations.*', 'subscription_plans.*')
would make the query return both columns. What am I missing? Happy new year!
PS: below is a copy of the dd() contents for the collection, with title only appearing once.
#attributes: array:44 [▼
"id" => 1
"title" => "Monthly Subscription"
"address_1" => "34 Florence Street"
"address_2" => ""
"suburb" => "Hornsby"
"state" => "NSW"
"postcode" => "2077"
"country_id" => 12
"currency_id" => 12
"time_zone_id" => 109
"phone" => "0392144497"
"website" => "http://www.Tremblay.com/est-aspernatur-et-ut-provident.html"
"business_id" => "82297955560"
"tax_registration" => 1
"logo" => "8aa656de-2bc2-4e14-dddd-e02fbcd2b76f"
"quote_terms_days" => 14
"invoice_terms_days" => 14
"fiscal_start_id" => 7
"industry_id" => 4
"company_size_id" => 3
"date_format_id" => 2
"date_time_format_id" => 20
"owner_id" => 1
"gateway_id" => "1"
"gateway_username" => "xxx"
"gateway_password" => "xxx"
"gateway_signature" => "xxx"
"gateway_accepted_cards" => "[1, 2, 3]"
"subscription_plan_id" => 1
"trial_ends_at" => "2015-11-07"
"grace_ends_at" => "2016-02-10"
"subscription_ends_at" => "2016-01-11"
"latitude" => "-33.70433500"
"longitude" => "151.10161900"
"registration" => "done"
"deleted_at" => null
"created_at" => "2016-01-01 14:59:47"
"updated_at" => "2016-01-01 14:59:47"
"amount" => "9.09"
"gst" => "0.91"
"gst_amount" => "10.00"
"billing_cycle" => "MONTH"
"trial_period_days" => 30
"grace_period_days" => 30
]
The "missing" title column contains:
'title' => 'ABC Electrical'
There is some misunderstanding as to what I suggested: instead of using *, you could list the field names one by one and provide aliases for the 2 title fields. This does not mean that you should keep the 'organisations.*', 'subscription_plans.*' and add the 2 title fields to the select list with aliases because this way you select both title fields twice, wasting memory and processor time.
You should not include the * forms in the select list, but list each field individually, with the 2 title fields marked with aliases:
public function getOrganisationsOwned()
{
// If the user is owner of any one or many organisations then return this list
return Organisation::leftJoin('subscription_plans', 'organisations.subscription_plan_id', '=', 'subscription_plans.id')
->where('organisations.owner_id', '=', $this->id)
->select('organisations.id', 'organisations.title AS org_title', ..., 'subscription_plans.subscription_plan_id', 'subscription_plans.title AS plan_title', ...)
->get();
}
Yeah, I know, listing so many field one by one is a pain in the ***, however, each field is retrieved once and only once, at it is clear that you are fetching what is needed.
#Shadow's suggestion worked, although you should note, this method allows you to select all the fields, but only "rename" columns or rather alias them so you can still access the proper value when using joins. The old value will still be overridden, but now you can use your alias with the correct value.
The below is now working:
public function getOrganisationsOwned()
{
// If the user is owner of any one or many organisations then return this list
return Organisation::leftJoin('subscription_plans', 'organisations.subscription_plan_id', '=', 'subscription_plans.id')
->where('organisations.owner_id', '=', $this->id)
->select('organisations.*', 'organisations.title AS org_title', 'subscription_plans.*', 'subscription_plans.title AS plan_title')
->get();
}

MySQL result multiple arrays

i.e : i have 2 tables
Product ( id, name )
Photo ( id, name, photo_id )
And I need to get result in array like this:
array(
'id' => 1,
'name' => product,
'photos' => array(
array('id' => 1, 'name' => 'photo1')
array('id' => 2, 'name' => 'photo2')
)
}
Is it possible in PHP using clear SQL?
I know that is possible to get 2 arrays and connect it but I have many records and I dont want to wase time to quering.
You have to add a foreign_key in your photo table "product_id".
Then create a method getPhotos() in your Product class with will collect all photos for your product.
Is it possible in PHP using clear SQL?
Not in a single SQL call. With a single call, this is the closest you can get:
array(
'id' => 1,
'name' => product,
'photo_id' => 1,
'photo_name' => 'photo1')
),
array(
'id' => 1,
'name' => product,
'photo_id' => 2,
'photo_name' => 'photo2')
)
Your only choice for the format you want is to run queries separately or to combine them into the data structure you want.
As mentioned, this is not possible with SQL. SQL is based on the relational model which is a 1-Normal-Form data model. That means, the result relation is also flat (no nested relations in a relation).
However, there are good frameworks which generate intermediary models in your corresponding target language (e.g. Python, Java, ...) that circumvent the impression of a flat data model. Check for example Django.
https://docs.djangoproject.com/en/1.8/topics/db/models/
Moo

Mongodb, using aggregate combined with filter?

I'm trying to convert a PHP script that is based in a mysql database to run it on a MongoDB database. I have resolved the major queries except one.
Imagine i have a library (this is the collection), every document is a book entry. So I need to know how many distinct authors are in the library wroten in a certain language (another field).
At the moment I have that code and I don't know how to continue:
$test = array(
array(
'$group' => array(
'_id' => array('author' => '$author' )
)
)
);
$out = $db->$collection->aggregate($test);
Thanks.
If you want to put a filter, you need to start the pipeline with a $match,the command will be:
db.collection.aggregate([
{ "$match" : {lang : "en"} },
{"$group":{"_id": {"author" : "$author"} , "total" : {"$sum" : 1} }}
])
If you convert that to PHP it will be:
$test = array(
array('$match' => array("lang" => "en")),
array(
'$group' => array(
"_id" => array('author' => '$author'),
"total" => array('$sum' => 1)
),
),
);
In this case you have to pass the language in the first step (match/filter).
If you want to could for "all languages" you just need to put the language in the $group operator
db.collection.aggregate([
{"$group":{"_id": {"author" : "$author", lang : "$lang"} , "total" : {"$sum" : 1} }}
])
I let you push this in PHP
You can find more informations about $match here:
http://docs.mongodb.org/manual/reference/operator/aggregation/match/

Categories