How to query "where" something equals something - yii2

Right so at the minute my query looks like this:
$subcategory = Subcategory::find()->asArray()->all();
this basically grabs all the data from my subcategory table and stores it into $subcategory.
However i want to find specific data. For example in my subcategory table i have a column called subcategory_id.
Now i want to pull back all the subcategories where subcategory_id = $firstcategory(This will be a number)
Im guessing that it is something like this, however it is not working. Any ideas on how to do this query?
$subcategory = Subcategory::find()->asArray()->all()->where('subcategory_id'
== $firstcategory);

There is no need to guess, just read the docs. Here is one of the ways to do it:
$subcategory = Subcategory::find()
->where(['subcategory_id' => $firstcategory]);
->asArray()
->all();
Note that order of using all() is crucial, once it's called you get the array of results and you can not modify query anymore.

Related

How to count total amount of comments per posts in nodejs, react js and sequelize?

I am working on a project where a user can ask and answer a question so in the comments filed I have trouble with it.
the comments table is working well and displaying the data and can delete the data, but I want to count the total number of comments per post.
These blooks of codes are working well but it counts all the comments in the table, that's what I don't want, I want to display the total number of each post not all the amount of the comments in one post.
router.get("/commentsCounter/:id", async (req, res) => {
const id = req.params.id;
const commentsCounter = await Comments.count(id);
res.json({commentsCounter});
console.log('commentsCounter', commentsCounter)
});
in the comment table, I have commentbody,author name, and postId.
Do any suggestions, please?
Sequelize count method takes an object as its argument which you can specify your post ID in its where attribute. So in your case you want to change your query to
const commentsCounter = await Comments.count({ where: { postId: id} });
Without seeing the full code (DB call, what the select statement looks like etc) it's hard to say..
But, typically if you DB is setup to have say 'posts' and 'comments' tables and the comment table has something like id AND parentID (the ID of the parent POST in the 'posts' table) you should be able to do it fairly easily using javascript OR the DB query itself
If you are doing it on the DB side, you would typically add a COUNT to the select statement OR once you have the results of the query you can just do a 'length' of the returned object to get the total returned.
*** Edit ***
As #Pouya had pointed out, you can doing via the SQL query as show in his post, this will count the number of responses based on the select, this does require a query per though, again without knowing the full flow of this this may or may not be what you are looking for but would give you the count based on the specific query.
Now, if you are say, returning a large object of ALL replies and want to get just the responses for a specific subset you will want to look at filtering your return object by the right key/value
something like
let myArr = [{id:'123',name:'item1'},{id:'234',name:"item2"},
{id:'123',name:"item3"}]
//filter just id 123
// filter syntax is [array].filter(variable => [key you want to filter on].includes("[value to filter on]")
let newArray = myArr.filter(p => p.id.includes('123'));
//our new array
console.log(newArray)
Should get you just a subset of the array, then you can just do
let replyCount = newArray.length

Rails, MySql, JSON column which stores array of UUIDs - Need to do exact match

I have a model called lists, which has a column called item_ids. item_ids is a JSON column (MySQL) and the column contains array of UUIDs, each referring to one item.
Now when someone creates a new list, I need to search whether there is an existing list with same set of UUIDs, and I want to do this search using query itself for faster response. Also use ActiveRecord querying as much as possible.
How do i achieve this?
item_ids = ["11E85378-CFE8-39F8-89DC-7086913CFD4B", "11E85354-304C-0664-9E81-0A281BE2CA42"]
v = List.new(item_ids: item_ids)
v.save!
Now, how do I check whether a list exists which has item ids exactly matches with that mentioned in query ? Following wont work.
list_count = List.where(item_ids: item_ids).count
Edit 1
List.where("JSON_CONTAINS(item_ids, ?) ", item_ids.to_json).count
This statement works, but it counts even if only one of the item matches. Looking for exact number of items.
Edit 2
List.where("JSON_CONTAINS( item_ids, ?) and JSON_LENGTH(item_ids) = ?", item_ids.to_json, item_ids.size).count
Looks like this is working
You can implement a has many relation between lists and items and then access like this.
List.includes(:item).where('items.id in (?)',item_ids)
To implement has_many relation:
http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

Laravel model query with only certain columns

I want to make a query that gets all the users from table "users" and i need to have only user.id.
$users = User::all();
this will get the whole model User but this is a real performance issue for my app. There is too much data going through.
I need to append some data for each user so i can calculate the working hours.
So the question is how to fetch all users without any other data except $user->id?
$name = DB::table('users')->select('id')->get();
For the certain columns, I think this is best:
$users = User::select('id')->get();
See Documentation.
Use the pluck() method:
$users = User::pluck('id');
The pluck method retrieves all of the values for a given key
Getting all User objects with id only:
$users = User::select('id')->get();
Getting all id as straight int value
According to documentation: https://laravel.com/docs/5.3/queries#selects
Specifying A Select Clause (most efficient)
$users = DB::table('users')->select('id')->get();
Retrieving A Single Column From A Row (but this will process all columns)
$name = DB::table('users')->where('name', 'John')->pluck('name');

Sorted array with specific items on top using Zend_Db_Select order()

I am trying to modify a plug-in that, among other things, alphabetically sorts an array from a mysql database. The part of the relevant PHP file that does the sorting looks like this:
$select->order("$alias.name ASC");
I want to continue to sort the items in ascending order, but I want to keep a specific item at the top (out of its alphabetical order).
From the information here it looks like the way to do this in MySQL would be simple, just:
ORDER BY name = 'Library' desc,
name asc;
But even studying the information here, I can't quite translate this into the order() function. I have tried:
$select->order("$alias.name ='Library' DESC","$alias.name ASC")
But it seems that it does not work quite that way.
Alright, found the answer-
I needed to use Zend_Db_Expr(). In case it is helpful to anyone else, this was solved like so:
$select->order(array(
new Zend_Db_Expr("$alias.name = 'Library' DESC"),
new Zend_Db_Expr("$alias.name ASC")
));

Top level MySQL statistics

Have not been able to find any information on this, I could do this in its own but I feel keeping it in the query might be the best option, if its possible.
Basically I want to try to add a top level "statistics" portion of a query.
So when I get the results I will see it like so
num_rows = 900
distinct_col = 9
results = array()
This way I can loop the results normally, and then pull out information that I would only need once outside of it. Is this possible?
EDIT:
I am not looking for the normal mysql statistics like num_rows exactly. But in a case where lets say you limit the results to ten, num_rows would return 10, but you want total results, so 900. In most cases I would just use another query and look just for the amount, however combining it all into one query logically seems faster for me. There is also more then just the num_rows I may need, say they are all products and have a specific category, I would need to count the amount of categories all items fall under. So looping the raw results when there is only one result for those columns is sillyness.
EDIT 2:
To clarify further I need to get some counts on some columns, and maybe a min-max result on a join. Having it return on every loop would work, but the same exact return uselessly returning on every loop when its only needed once does not seem logical. I am no MySQL expert and am mainly just trying to make sure I come up with the most logical and fastest method to get the required data.
Here is a PHP return example:
array(
[num_rows] => 900,
[categories] => 9,
[min_price] => 400,
[max_price] => 900,
[results] => array(
[0] => //row array
[1] -> //row array
)
);
Mysql returns its default num rows before you "fetch" the results, having custom results added there may be sufficient.
Dunno why do you need that but that's very easy to get
Assuming you are using safeMysql (though you can use whatever way to get data into array)
$results = $db->getAll("SELECT * FROM t");
$num_rows = count($results);
$num_cols = count($results[0]);
that's all
I am mainly just trying to make sure I come up with the most logical and fastest method to get the required data.
Yes, you are.
Nothing wrong with getting aggregated data with every loop.
As for the count beyond LIMITs - when you need it, you can use mysql's SQL_CALC_FOUND_ROWS / FOUND_ROWS() feature