PHP/MySQL Activerecord, get relationship row count - php

I have two tables:
media_folders
id, title
media
id, folder_id, title
They each have their own model
Media, MediaFolder. Nothing special about them except they have the static $table_name property set. Now I can assign a $has_many to the MediaFolder class which will find all associated Media. However, All i need is to get the number of media within a mediafolder and not the actual objects themselves. I want to end up with an attribute in a MediaFolder object called files which has a count of how many media rows has a folder_id of the current folder.
How would i do this?

Understand your case, but not your exact problem so can you provide some more details like:
1. does your problem is with building SQL query?
2. does your problem with building query using active records.. (if yes which framework you are using)
Need some more description.

If it's just some SQL :
$sql = "SELECT mf.folder_id, count(m.id) as files
FROM media_folders mf, media m
WHERE mf.id = m.folder_id
GROUP BY mf.folder_id"

Related

laravel get eloquent data using its relations Ids

I have three main mySQL tables:
users
tags
news_articles
I also have many to many tables to connect them as needed.
I want to grab all the articles that share the same tags as users so I can personalise their experience.
(example): say a user has tags for "Trump" or "Brexit" I want to grab all the news articles that also have Trump or Brexit.
I could grab the whole data pool and make calculations but that might get unnecessarily server intensive so is there a way of doing it through Eloquent?
Also is Eloquent capable of tallying the user tags to determine which tags the user is most interested in before grabbing the articles or would that need a workaround after?
Thanks in advance.
Christophvh's response did work for me in the end. After some more time with Eloquent I found plenty more ways of doing this.
A way I would go about this now for anyone who happens to be stuck:
By creating a tags method in my User and Article models to return all related tags I can then do the following.
$userTags = $user->tags()->pluck('name')->get()->toArray();
$articles = Article::whereHas('tags', function($tag) use ($userTags) {
$tag->where('name', $userTags)->get();
})->get();
The above code should:
Get only the name field of all tags belonging to a user and store them in an array.
Grab all articles where their related tags name field contain any tag in the $userTags variable
To create a priority tags list I would just need to run array_count_values($userTags) and order it by the returned values, then pass the new ordered $userTags array into the Eloquent query.

Create A List From a Category Section in mysql

I was wondering if mysql has a way to look at a column and only retrieve the results when it finds a unique column once. For example
if the table looks like this:
id name category
1 test Health
2 carl Health
3 bob Oscar
4 joe Technology
As you can see their are two rows that could have the same category. Is their a way to retrieve the result where the array will one only return the category once?
What I am trying to do is get all the categories in the database so I can loop through them later in the code and use them. For example if I wanted to created a menu, I would want the menu to list all the categories in the menu.
I know I can run
SELECT categories FROM dbname
but this returns duplicate rows where I only need the cateogry to return once. Is there a way to do this on the mysql side?
I assume I can just use php's array_unique();
but I feel like this adds more overhead, is this not something MYSQL can do on the backend?
group by worked perfectly #Fred-ii- please submit this as answer so I can get that approved for you. – DEVPROCB
As requested by the OP:
You can use GROUP BY col_of_choice in order to avoid duplicates be shown in the queried results.
Reference:
https://dev.mysql.com/doc/refman/5.5/en/group-by-handling.html
By using database normalization, you would create another table with an unique id and the category name and by that link those two together, like
select * from mytable1
on mytable1.cat = mytable2.id
group by mytable1.cat
You can ofcourse also use group by without multiple tables, but for the structure, I recommend doing it.
You can use select distinct:
SELECT DISTINCT categories
FROM dbname ;
For various reasons, it is a good idea to have a separate reference table with one row per category. This helps in many ways:
Ensures that the category names are consistent ("Technology" versus "tech" for instance).
Gives a nice list of categories that are available.
Ensures that a category sticks around, even if no names currently reference it.
Allows for additional information about categories, such as the first time it appears, or a longer description.
This is recommended. However, if you still want to leave the category in place as it is, I would recommend an index on dbname(categories). The query should take advantage of the index.
SELECT id, name from dbname GROUP BY categoryname
Hope this will help.
You can even use distinct category.

Update Field using a set of IDs from another table at random

I have 3 Tables. model, category, and document. Documents belong in a category, which belongs to a model, and models can have multiple categories, which can have multiple documents.
I'm trying to build & execute this query in PHP, assigning each document a randomly selected category from a list of the categories in the currently selected model.
So, if a model has 10 categories (cat1-cat10), with each of those categories having 10 documents, the end result would make 1000 documents have a random_category_id field of cat1 - cat10 assigned at random, but not overwriting the existing category_id of the document.
Later in the application, I need to be able to calculate when document.category_id == document.random_category_id.
Is there a way to do this in one query. I'm new to SQL & PHP (and haven't mastered any kind of JOIN yet), so please forgive the blunders in database design & mixed coding approaches. I know the below example will not execute.
I'm using MySQL 5.5.28 with InnoDB.
Pseudocode Example
$catList = SELECT category_id FROM category WHERE model_id = '$current_model_id'
UPDATE document.random_category_id = RANDOM($catList) WHERE document.model_id = '$current_model_id'
Thank you!

How can I look in different table to see if a page is active?

Some difficulties with "condition"
I have a table Tags with fields : id, name, count
I have table PagesTags with fields : id, page_id and tag_id
I have table Pages with several fields : id, name, shownmenu, onilne.
In my TagsController, I have a simple code to extract and display the Tags
function tagsList(){
//$this->loadModel('PageTag');
return $this->Tag->find('all',
array('order'=>'name ASC','conditions'=>array('Tag.count >= 0')));
}
The problem is, I do not want to display the tags associated to a page which is Offline.
Then in my aboce I should use somethink like $this->loadModel('PageTag'); to get the Id of the associated page and a second $this->loadModel('Page');
to get the page status 'online' (true/false)
Can we do it at once?
How can I do it simply?
How can I look in two table at one?
You need to use model relationships to link your models together. Read the manual about it or see my answer on this topic here:
CakePHP 1.3 - Unknown column in where clause
In your case, PagesTags hasOne Page and hasMany Tags. You will write these relationships into the model. Also you will write into Tags model that it hasOne PagesTags, which will in turn retrieve the associated Page.
After you have done all of that, you don't need to call loadModel, you just query Tag and it will implicitly join the associated PagesTags and Page records, so you can just put this into your conditions:
'Page.status !=' => 'Offline'
I think the relation of the table is HABTM so you have to look this component for searching http://bakery.cakephp.org/articles/Kumazatheef/2008/10/22/habtm-searching

Selecting rows from MySQL

I'm trying to create a web index. Every advertiser in my database will be able to appear on a few categories, so I've added a categorys column, and in that column I'll store the categories separated by "," so it will look like:
1,3,5
The problem is that I have no idea how I'm supposed to select all of the advertisers in a certain category, like: mysql_query("SELECT * FROM advertisers WHERE category = ??");
If categories is another database table, you shouldn't use a plain-text field like that. Create a "pivot table" for the purpose, something like advertisers_categories that links the two tables together. With setup, you could do a query like:
SELECT A.* FROM advertisers AS A
JOIN advertisers_categories AS AC ON AC.advertiser_id = A.id
WHERE AC.category_id = 12;
The schema of advertisers_categories would look something like this:
# advertisers_categories
# --> id INT
# --> advertiser_id INT
# --> category_id INT
You should design your database in another way. Take a look at Atomicity.
Short: You should not store your value in the form of 1,3,5.
I won't give you an answer because if you starting you use it this way now, you going to run into much more severe problems later. No offense :)
It's not possible having comma-separated values to do this strictly in an SQL query. You could return every row and have a PHP script which goes through each row, using explode($row,',') and then if(in_array($exploded_row,'CATEGORY')) to check for the existence of the category.
The more common solution is to restructure your database. You're thinking too two-dimensionally. You're looking for the Many to Many Data Model
advertisers
-----------
id
name
etc.
categories
----------
id
name
etc.
ad_cat
------
advertiser_id
category_id
So ad_cat will have at least one (usually more) entry per advertiser and at least one (usually more) entry per category, and every entry in ad_cat will link one advertiser to one category.
The SQL query then involves grabbing every line from ad_cat with the desired category_id(s) and searching for an advertiser whose id is in the resulting query's output.
Your implementation as-is will make it difficult and taxing on your server's resources to do what you want.
I'd recommend creating a table that relates advertisers to categories and then querying on that table given a category id value to obtain the advertisers that are in that category.
That is a very wrong way to define categories, because your array of values cannot be normalized.
Instead, define another table called CATEGORIES, and use a JOIN-table to match CATEGORIES with ADVERTIZERS.
Only then you will be able to properly select it.
Hope this helps!

Categories