Laravel sorting by sum of remote column? - php

So I have a table film that has various information in it, picture, title, director, ID, etc. I also have a separate table called votes. The votes table has id, filmId, value. Default value is 1, but this can change depending on who votes (weighted votes) so I am trying to call a eloquent query that will get films in order of their value sum. Based on another stackoverflow question I have come up with this.
$films = Film::join('votes', 'films.id', '=', 'votes.filmId')->orderBy(DB::raw('sum(\'votes.value\')'), 'DESC')->groupby('votes.filmId')->get();
This does not work as intended. Basically I want to go to the votes table, grab all the votes that correspond to a film id and sum up the value column and order by that. Any ideas on how this can be done?

Related

SELECT FROM 100 tables in 1 database

I am trying to SELECT id, description, title FROM table1, table2, table100
Say I get this working, is it better for me to just combine all my tables in phpmyadmin?
The problem is I have around 100 tables all of different categories of books so I want to keep them seperated in their individual tables.
I am trying to make a search engine that searches all the books in the entire database. All tables have the same column names.
So really all I really am trying to do is search the entire database's tables for an id, description, title. My search works, just I can only search 1 table and every solution online I have found only really works efficiantly with 2 or 3 tables.
Thanks in advance.
The best is to redesign your database, everything into a single table with an additional "category" column.
in the meantime, you can create a view which union the tables with an additional column for the category.
I recommend redesign the model and unifique this 100 tables to 1, and add a new column with category but integer value, not string value. In this way, you can index the category column with the other fields (id, description, title) for speed up the query.
This resolution is more easy for avoid pain later.
I recommend keeping one table A with id, description, title, category and create another table B with categories. Table A has to have a foreign key with table categories. Then create a query to retrieve the books with a specific category.
Example:
SELECT id, description, title, category FROM books WHERE category = "drama"
I think it speaks to the database design itself as mentioned by most here. You've a few options depending on how much time you have on your hands:
(Short Term / Quick Fix) Central table with all your current fields plus category as a flag to differentiate between the current tables you have. So your insert will be something like "INSERT INTO newtable (ID,AssetID,ServiceID,Category) SELECT id, description, title, 'Fiction' FROM table1 ;"
If you tables are incrementally named like table1, table2 upto table100, you could then maybe write a quick php script that will iterate through the insert loop while incrementing on table on each iteration until the last table.
In the long run, you could invest in a json field that will house all your other data excluding keys that pertaining to a single entry

How to retrieve count values as multiple columns using group by in single query in MySQL?

I am writing a complex MySQL query. My actual query is more complex than I mentioned below.
I have a table named example and columns are id, name, option_1, option_2 . Of course id column is PK . I want to retrieve like this:
SELECT `id`,`name`,count(`option_1`),count(`option_2`)
My problem is I want to use "GROUP BY `id`" for count(`option_1`) and "GROUP BY `name`" for count(`option_2`) respectively. Now I have to break down it into multiple code in my php code.
How can I achieve what I want in a single query?
What you're asking for doesn't make a ton of sense. You want option 1 grouped by id and option 2 grouped by name, and you want to show all four columns in one result set.
First of all, if id is a primary key, then the count will just be the number of rows in the table since there will be no duplicate ids.
Second, even if id wasn't a primary key, and there were duplicate values, the grouping is different, so the counts represented in your result set would be grouped incorrectly.
Given that id is a primary key, perhaps your intention is actually to get a total count of the rows in the table. Perhaps this query would suit your needs?
SELECT
name,
COUNT(option_2) AS options
FROM
example
GROUP BY
name
UNION ALL
SELECT
'Total' AS name,
COUNT(*) AS options
FROM
example
This should get you a count of all the option_2 values, grouped by name, with the final row having a name of 'Total' and the count being the total number of rows in the table.
Aside from that, I'm not sure you're going to find the answer you're looking for due to the problems you would encounter matching up groupings.

Select from database with count and count based conditions?

I have a table with data relating to a user, and two important columns:
refer_count, which is updated when a new entry is made in the table with the referred_by column set to that users user_id, and referred_by which is the user_id of the of the user that referred them.
I want to select the users from the table that have the highest number of referrals after a certain date.
For example:
If there are 3 users, one of which referred the other 2 (lets say users 2 and 3), however user 2 was referred on the 2/12/14, whereas user 3 was referred on the 3/1/15.
If the cutoff is 1/12/14, then user 1 is returned with refer_count set to 2, but if the cutoff is after 2/12/14, then user 1 is returned with refer_count set to 1.
I've been thinking of how to do this, but I can't think of a way that would work. Is there a way?
This is via MySQL.
EDIT: I think I may need to provide for information.
The date registered (register_date) is used as the refer date. I need the refer_count to be updated with the number of users referred after the cutoff, however I need to get the actual user. This is for a 'top referrers' table. I can't figure out why I'm having so much trouble thinking of a way to do this.
SELECT user_id FROM usertable WHERE (referal_date BETWEEN '2014-12-2' AND CURDATE())ORDER BY refer_count DESC;
That's the rough idea.
You should look into normalizing your tables if you're keeping that all in the same table, though. It'd be better to keep referals in a seperate table.
Get the row with the maximum in refer_count with a Date condition for your referal_date such that it's after the certainDate:
SELECT user_id FROM table WHERE refer_count = (SELECT MAX(refer_count) FROM table) AND referal_date>certainDate;
Note that WHERE is before SELECT so it will not get the highest count first, but will filter with the date condition then get the highest count.
Edit: Updated query based on edited question.

Best method for storing quiz results in MySQL

I'm trying to record test/quiz scores in a database. What's the best method to do this when there might be a lot of tests and users?
These are some options I considered: should I create a new column for each quiz and row for users, or does this have its limitations? Might this be slow? Should i create a new row for each user & quiz? Should I stick to my original 'user' database and encode it in text?
Elaborating a little on the plan: JavaScript Quiz, submits score with AJAX, and a script sends it to the database. I'm new with php so i'm not sure about a good approach.
Any help would be greatly appreciated :) this is for a school science fair
I'd suggest 3 data tables in your database: students, tests, and scores.
Each student needs to have fields for an ID and whatever else (name, dob, etc) you want to record about them.
Tests should have fields for an ID and whatever else (name, date, weight, etc).
Scores should have the student ID, a test ID, and the score (any anything else).
This means you can query a student and join with the scores table to get all the student's scores. You can also join the test table these results to get labels put onto each score and calculate a grade based on scores and weight.
Alternately you can query for a test and join with the scores to get all the scores on a given test to get the class stats.
I would say create a database table, maybe one that lists all students(name, dob, student id), and then one for all tests(score, date, written by). Will only you access the db, or can your students access it too? If the latter is the case, you need to make sure the create accurate security or "views" to ensure the student can only see their own grades at a time (not everyone's).
Definitely do not create dynamic columns! (no column for each quiz). Also adding columns to user table (or generally any table) when they are not identifying the user(or generally any table item) is bad aproach...
This is pretty example of normalization, you should avoid storing any redundant rows. To do that you would create 3 tables and foreign keys to ensure scores are always referencing an existing user and quiz. E.g.:
users - id, nickname, name
quizzes - id, quizName, quizOtherData
scores - id, user_id (references users.id) , quiz_id , (ref. quizzes.id), score
And then add rows to scores table per user per quiz. Additionaly you could create UNIQUE key for columns user_id and quiz_id to disallow users to complete one quiz more times than one.
This will be fast and will not store redundant (unneeded extra) data.
To get results of quiz with id e.g. 4 and user info of people who's submitted this quiz, ordered from highest to lowest score, you would do query like:
SELECT users.*, scores.score
FROM scores RIGHT JOIN users ON(users.id=scores.user_id)
WHERE scores.quiz_id = 4
ORDER BY score DESC
Reason why I used RIGHT join here is because there might be users that didn't do this quiz, however every score always have an existing user&quiz (due to foreign keys
To get overall info of all users, quizes and scores you would do something like:
SELECT *
FROM quizzes
LEFT JOIN scores ON(quizzes.id=scores.quiz_id)
LEFT JOIN users ON(users.id=scores.user_id)
ORDER BY quizzes.id DESC, scores.score DESC, users.name ASC
BTW: If you are new to PHP (or anybody reading this), use PHP's PDO interface to communicate with your database :) AVOID functions like mysql_query, at least use mysqli_query, but for portability I would recommend stay with PDO.

Get the sum of a column value for all rows with same value in different column

I need to know how to handle a pretty complex situation.
I have a system that allows users to vote up or down on comments that others make. I want to create a report of those with the most up votes based on all of their comments. The upvotes were not tracked in the users table, only in the comments table so it needs to go through the comments table and get the value in the vote column and output the sum of all of the vote column values for each userid. It then needs to order these and output the top 10.
Thanks in advance for help
If you post your users and comments table structure I could make a query. But it would be something like this:
SELECT SUM(votes) total, user_id FROM comments GROUP BY user_id ORDER BY total LIMIT 10

Categories