What is a right way to use like in SQL - mysql

I am working on "Not Boring Movies" problem in leetcode.
The porblem describes as following
"X city opened a new cinema, many people would like to go to this cinema. The cinema also gives out a poster indicating the movies’ ratings and descriptions.
Please write a SQL query to output movies with an odd numbered ID and a description that is not 'boring'. Order the result by rating."
For example, table cinema
+---------+-----------+--------------+-----------+
| id | movie | description | rating |
+---------+-----------+--------------+-----------+
| 1 | War | great 3D | 8.9 |
| 2 | Science | fiction | 8.5 |
| 3 | irish | boring | 6.2 |
| 4 | Ice song | Fantacy | 8.6 |
| 5 | House card| Interesting| 9.1 |
+---------+-----------+--------------+-----------+
For the example above, the output should be:
+---------+-----------+--------------+-----------+
| id | movie | description | rating |
+---------+-----------+--------------+-----------+
| 5 | House card| Interesting| 9.1 |
| 1 | War | great 3D | 8.9 |
+---------+-----------+--------------+-----------+
My solution is:
SELECT id, movie ,description, rating
FROM cinema
WHERE ID % 2 != 0 AND description NOT LIKE %boring%
ORDER BY rating DESC
This solution can not past leetcode test.
The expected solution is:
SELECT id, movie ,description, rating
FROM cinema
WHERE id % 2 != 0 AND description != 'boring'
ORDER BY rating DESC
Basically, both solution follow the same idea to solve the problem, but I can not understand the difference between them. Can anyone tell me why my solution falls to past the test?

The answer isn't accepted, because they want you to filter out rows with descriptions that are exactly "boring", and not rows that have descriptions like, e.g., "not boring" or "only a little boring". Your query would filter out all three rows.

The problem description clearly states ...description that is not 'boring'. It doesn’t say “not containing”, it says “is not”
contain is LIKE in sql and is is = in sql

LIKE %boring% will select
_boring!
...boring...
etc
But the description value is just "boring"

you should use ('%boring% ') on your like
SELECT id, movie ,description, rating
FROM cinema
WHERE ID % 2 != 0 AND description NOT LIKE '%boring%'
ORDER BY rating DESC

Related

Mysql - BIGINT value is out of range in error using substring_index

select substring_index(SUBSTRING_INDEX(title, ' ', title+1), ' ',-1) as word ,
COUNT(*) AS counter
from feed_collections
group by word
ORDER BY counter DESC;
The table has 1785123 rows and I thing this is the problem.
This is the error query (1690): BIGINT value is out of range in '(feed_collections.title + 1)' and I don't know how to fix it.
The query worked until around 1500000 rows.
The table contains 3 columns: title(text), url(text), date(datetime).
The code is finding most common words in column title
Example:
Table
+----------------------------------+-----------------+
| title | url |
+----------------------------------+-----------------+
| the world of ukraine | www.ab |
| count the days until christmas | www.abc.com |
| EU and NATO wants to use bombs | www.abcd.com |
| Ukraine needs help from NATO | www.abce.com |
+----------------------------------+-----------------+
Result
+------+-------+
| word | total |
+------+-------+
| nato | 5 |
| of | 14 |
| and | 11 |
| To | 9 |
| that | 7 |
| ukraine | 2 |
| EU | 1 |
+------+-------+
I adapted the code from here:
How to find most popular word occurrences in MySQL?
This works with small data. Seems to be a problem when tries to filter large data.
What I'm trying to achive in the future is to find most common words in the title column grouped by 1,2,3,4,5,6,7 words.
It will exists a select box to select how many words to use.
Example:
I will select to find most common words with 4 words.
Title: 1. Nato is using force , 2. Eu and Nato is using force.
Results with 4 words:
'nato is using force' found 2 times in title.
Any idea how to fix or how to do a query for this?
I'm working with laravel, a solution would be to create a php method...

SQL ORDER BY using a value in another table using an equation grouped by duplicates

I have been given a movie database and I am trying to order by user rating held in a separate table to my movie information.
My problem is that my database does NOT have an overall rating of a movie, but only singular user ratings attached to that movie. But I want to order it by the overall average rating
For example:
SELECT Movies.title, Movies.movie_id, Movies.poster, Ratings.rating
FROM Movies INNER JOIN Ratings
ON Movies.movie_id = Ratings.movie_id
WHERE genre LIKE '%action%' AND (origin = 'american')
ORDER BY Ratings.rating DESC;
*(Rating is only selected to showcase to you the values, I do not need to use them outside this query)
This works out to display
+-------------------------+----------+------------------------------------+--------+
| title | movie_id | poster | rating |
+-------------------------+----------+------------------------------------+--------+
| The Baytown Outlaws | 2 | posters/The Baytown Outlaws.jpg | 5 |
| A Dark Truth | 8 | posters/A Dark Truth.jpg | 4 |
| A Dark Truth | 8 | posters/A Dark Truth.jpg | 3 |
| American Made | 14 | posters/American Made.jpg | 3 |
| Avengers: Age of Ultron | 4 | posters/Avengers Age of Ultron.jpg | 3 |
| Romeo Must Die | 1 | posters/Romeo Must Die.jpg | 3 |
| Avengers: Age of Ultron | 4 | posters/Avengers Age of Ultron.jpg | 2 |
| Fast & Furious 6 | 3 | posters/Fast & Furious 6.jpg | 2 |
| Olympus Has Fallen | 9 | posters/Olympus Has Fallen.jpg | 1 |
+-------------------------+----------+------------------------------------+--------+
Now from this I want to have my query select groups based on movie title, add up the ratings of that group, average that value, and then order titles by that average and excluding duplicate title names from the return
So my ideal query would return:
+-------------------------+----------+------------------------------------+
| title | movie_id | poster |
+-------------------------+----------+------------------------------------+
| The Baytown Outlaws | 2 | posters/The Baytown Outlaws.jpg |
| A Dark Truth | 8 | posters/A Dark Truth.jpg |
| American Made | 14 | posters/American Made.jpg |
| Romeo Must Die | 1 | posters/Romeo Must Die.jpg |
| Avengers: Age of Ultron | 4 | posters/Avengers Age of Ultron.jpg |
| Fast & Furious 6 | 3 | posters/Fast & Furious 6.jpg |
| Olympus Has Fallen | 9 | posters/Olympus Has Fallen.jpg |
+-------------------------+----------+------------------------------------+
So this returns my movie info ordered by average rating then excluding duplicate titles
Baytown Outlaws has 1 rating at 5 -> overall 5
Dark Truth has 2 ratings at 4 and 3 -> overall rating of 3.5 but only displays one row of movie info
American Made has 1 rating at 3 -> overall 3
etc.
I am having a lot of trouble figuring out this exact query, or if it is even possible. Any help or keyword suggestion would be useful as I am somewhat new to SQL and don't know all of its strengths. If not possible, I would also appreciate an answer saying so, so that I can go ahead and rework the database system to instead follow a better system of saving the overall rating within the Movies table.
A combination of COUNT(*) and SUM(rating) group by movie_id (or title).
Something like this:
SELECT Movies.title, Movies.movie_id, Movies.poster, SUM(Ratings.rating)/COUNT(*) AS avg_rating
FROM Movies INNER JOIN Ratings
ON Movies.movie_id = Ratings.movie_id
WHERE genre LIKE '%action%' AND (origin = 'american')
GROUP BY Movies.movie_id ORDER BY avg_rating DESC;
It can be done with the AVG function and a group by on multiple columns.
The tricky part of using AVG in that case is that when using such a function, every element in the SELECT part must either be in the GROUP or be an aggregate function. That being said, If you make groups by a combination of ID and Movie title, you would obtain the same result (in this case) as if you grouped by ID only.
You can use that to your advantage to add these columns in your SELECT section while using the AVG aggregate function.
In your first table, every time you look at the A Dark Truth movie, it comes with the same id, 8. Every time you look at the value Avengers: Age of Ultron, it comes with the same id, 4.
I suggest taking a few minutes and drawing a Venn diagram of the problem to get a good grasp of it as it seems this is material of a class.
I made a fiddle to demonstrate it for you. You can play around with it and add your initial join and where to complete it, I did a slight variation of the initial model, the create table is also in the fiddle.
SELECT Movie_id, Title, Poster, AVG(Rating)
FROM MoviesRatings
GROUP BY Movie_id, Title, Poster
ORDER BY AVG(Rating) DESC

Get clan with bigger kills/deaths coef

I got table:
id | nick | clanid | kills | deaths | map
1 | xdd | 2 | 123 | 23 | 'map_1'
2 | xd | 1 | 23 | 32 | 'map_1'
this table continuing with similar records. I need to get only 1 result, it's should be clanid and coef(kills/deaths), of course i need the clan with higher coef. This table got many records with players which have different clanids, kills, deaths and map.
The complete result i need: it's clanid with higher coef at current map.I tried SQL like that:
SELECT `clanid`, SUM(kills)/SUM(deaths) as 'coef'
FROM `test_user_stats`
WHERE `map`='map_1'
But that returs only 1 record with last clanid and his coef.
What i have to do next?(i obviously need to use LIMIT 1 and ORDER BY coef, but i got problems even without going so far).

Error in Mysql query with LIKE %...%

I am trying to update a table using another table. I am not able to determine how to use LIKE %…% feature here. Please help me out.
Table1:
TableToBeUpdated:
id | location | value
------------
1 | california | I am going to be here soon.
2 | Nill | Hello I love playing chess and yes.
3 | Nill | my hotel room is just shitty!
4 | Nill | Why on earth God doesn’t live on earth!
5 | Nill | friends of friends and their dogs.
Table2:
TableToCheckFrom :
uniqueid | location | keyword
---------------------
1 | Texas | Why on earth
2 | NewYork | friends and their
3 | Washington | love playing chess
4 | NewYork | their dogs
The result should be:
id | location | value
------------
1 | California | I am going to be here soon.
2 | Washington | Hello I love playing chess and yes.
3 | Nill | my hotel room is just shitty!
4 | Texas | Why on earth God doesn’t live on earth!
5 |NewYork| friends of friends and their dogs.
——
I am using this formula but its giving me constant error:
UPDATE TableToBeUpdated, TableToCheckFrom
SET TableToBeUpdated.location = TableToCheckFrom.Location
WHERE TableToBeUpdated.Value LIKE %TableToCheckFrom.Keyword%
Thanks in Advance!
You need to put the % in quotes and concatenate them to the keyword. And you need to join the two tables so you can refer to columns from both of them.
UPDATE TableToBeUpdated AS u
JOIN TableToCheckFrom AS c ON u.Value LIKE CONCAT('%', c.Keyword, '%')
SET u.location = c.Location
You query is wrong (you never tell the DBM that you want to access the TableToCheckFrom table).
For an idea on how write such queries look at this question
Update mysql table with data from another table
If you find the like %% as an additional difficult strip it: first prepare a working query with a simply condition and then add the like one.

Optimising table design or optimising the query

I am trying to decide which one is better: to design a table that wastes a lot of space and has a simple query OR to write a very tight table but then the process of finding what I am looking for would be very processing intense.
The actual problem is this:
Imagine you have a very simple table. 1st column for the ID number the 2nd is a list of names and the 3rd is a list of names too. The 2nd column is a list of people who owe to the people in the 3rd column.
The search should do the following:
I search for a name in the 3rd column and see who owes this person in the 2nd column. A name or multiple names come up, then I want to see who owes them, again a bunch of names come up, and so on to level 5.
Maybe this is a well known scheme for which there is a well known simple answer in table design or MySQL circles. Could anybody suggest a MySQL query or perhaps an appropriate table design where I can use a simple query?
Example
ID owes owned to
1 Peter John
2 John George
3 Abdul George
4 George Anna
So I could design a wasteful table like this
ID 1 2 3 4 5
1 Anna George Abdul
2 Anna George John Peter
3 George Abdul
4 George John Peter
5 John Peter
But this would be very wasteful and bad bad design but it would be very easy to access the data along with the hierarchy and the owing chain.
Something like this seems suitable:
people
+----+--------+
| id | name |
+----+--------+
| 1 | Marty |
| 2 | Steven |
| 3 | John |
+----+--------+
With the table building the relationships between people owed and owing:
loans
+-----------+-------------+
| lender_id | borrower_id |
+-----------+-------------+
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
+-----------+-------------+
You could get all the people owing a given lender with something as simple as:
SELECT people.id, people.name
FROM loans
INNER JOIN people ON people.id = loans.borrower_id
WHERE loans.lender_id = X
Where X is the id of the lender. Given the lender_id of 1 (Marty) for example would yield:
+----+--------+
| id | name |
+----+--------+
| 2 | Steven |
| 3 | John |
+----+--------+
You can repeat this process for each of the resulting people until there are no results (no one being owed).