Show publications according to the interests of the users - php

I want to show publications according to the interests (in keywords) of the users.
USERS TABLE
id | username
5 | joelsilva
PUBLICATIONS TABLE
id | publication title
8 | The best car of the year!
TABLE OF INTERESTS
id | username | interest
8 | joelsilva | car
9 | joelsilva | year
It shows all the publications with the car title and year on the home page.
I've tried this:
$pubs = mysql_query(
"SELECT *
FROM PUBLICATIONS
WHERE (interest LIKE '%".$interests."%')
ORDER BY id desc"
) or die(mysql_error());
It works, but only with one type of interest in the table. If adding more than one interest shows nothing.

Join the publications and the interests on the title containing the interest and get the distinct rows of publication. Filter for the user.
SELECT DISTINCT
p.*
FROM publications p
INNER JOIN interests i
ON p.title LIKE concat('%', i.interest, '%')
WHERE username = ?
ORDER BY p.id DESC;
(BTW: Instead of the user's name, their ID should be in the interests table. And you should probably have a look here to learn why you shouldn't use string concatenation when building queries but parameterized queries.)

Related

MySQL Duplicating Row Results in Table When Searching Across Multiple Tables

I have three tables in a mySQL db one for users, one for colours and one for the linking of the users to the colours
Table 1 users
==============
ID | Name
--------------
1 | John
2 | Jayne
3 | Fred
Table 2 colours
==============
ID | Colour
--------------
1 | Blue
2 | Red
3 | Yellow
Table 3 link
==============
ID | Name | Colour
--------------
1 | 1 | 1
2 | 1 | 2
3 | 2 | 1
4 | 3 | 2
5 | 3 | 3
As you can see, some users have more than one favourite colour (yeah, i know, how annoying).
At the moment, I can show them in a table, with their favourite colour(s) in a column.
BUT, I want to be able to filter the table results by colour.
I can do it no problem with having a filter of just one colour, BUT the problem comes along with two colours.
If I want to see which user has selected for example Blue AND Red, I get a result of zero.
How can I get this result, without creating a search which results in each row being dedicated to a colour and then in turn showing the same user twice (one for red one for blue).
I hope this makes sense
THANKS IN ADVANCE
EDIT
An example query I have used is
SELECT * FROM users, colours, link WHERE users.id = link.name AND link.colour = colours.id
Alternatively to show for specific colour
SELECT * FROM users, colours, link WHERE users.id = link.name AND link.colour = colours.id AND link.colour = 1
But for double filter which shows duplicates
SELECT * FROM users, colours, link WHERE users.id = link.name AND link.colour = colours.id AND link.colour = 1 OR link.colour = 2
If that looks right here is the code:
SELECT Name FROM users
WHERE ID IN (SELECT DISTINCT(Name) AS Name
FROM link L
WHERE 2 IN (SELECT Colour FROM link L2 WHERE L.Name = L2.Name)
AND 1 IN (SELECT Colour FROM link L2 WHERE L.Name = L2.Name))
And now let me try to explain what L and L2 are... First sorry for my English I'll do my best to make a sense for you...
We make subquery on the same table here so we need to use alias for the table. Alias we use to give temporary name table or column which will be used only for that query.
Example for alias is when we select some column from table (Price and Quantity) and let's say we want to calculate Price * quantity and SELECT that column as total (total will be the name of that column in table which we return after we execute the query). Column name total well be give alias. we crate alias like:
SELECT Price, Quantity, (Price * Quantity) AS **total**
FROM t1...
That will return table with three column Price, Quantity, Total... if we don't use this AS total the name of that column will be Price * Quantity...
So here we use L and L2 just to know which column Name is from which part of SELECT query. If we wouldn't use alias in subquery
SELECT Colour FROM link L2 WHERE L.Name = L2.Name
we would have problem because subquery which locks like this:
SELECT Colour FROM link WHERE Name = Name
Doesn't make a a lot of sense, isn't it?
So basically we temporary rename table in this query because we need to know which column from which table we compere whit other one, in other way database will have a problem what to select...
I hope this make a sense for you. If you have any further question fill free to ask I will do my best to try to explain it to you.
I hope i didn't make it more complicated than it is...
GL!
EDIT
Hi there again, i worked something and and i figured out that your question probably have better answer than the first i give you... Hope it's not too late!
SELECT u.Name
FROM users u
INNER JOIN link L
ON u.ID = L.Name
INNER JOIN link l2
ON L.Name = L2.Name
WHERE L.Colour = 2 AND L2.Colour = 1
Look SQL Fiddle for that...

Like structure table with Laravel and showing the most popular content at top

I am using Laravel to creating a website, my users can post questions and other users can write their comments under the post, each comment have Up vote and Down vote, and users can voting for comments.
I need most liked (Up vote) shows topper than others..
This is my database structure and I join them together:
comment table:
comment_id | question_id | user_id | timestamp
up and down votes table (like):
like_id | comment_id | like_type | user_id | timestamp
note:like_type is an enum on mysql and its values are upvote and downvote.
1-What is the mysql query and Laravel codes for that?
2-Is my database Structure right?
1.Calculate SUM belongs to Each Comment
2.Make it order by Desc
select * from (
select ct.comment_id,ct.question_id,
ct.user_id,SUM(case when vt.like_type='upvote' then 1 else -1 end )
cnt from commenttable ct
from votestable
vt left join
on
vt.comment_id=ct.comment_id
)D order by D.cnt desc

Select records from one table and sort the result using a column from another table

I'm working on payroll system for the CRM located at my work and I'm trying to save having to store redundant data which over a period of years will stack up.
I tried to relate it to "how to get value from mysql table ordered by another table?" but had no luck.
I have a Users table
===========================================
# id | username | first_name | last_name #
===========================================
# 1 | joe | Joe | Blow #
===========================================
I also have a Timesheets table which stores the data of each individual session which for the sake of keeping short I have condensed a little in this question and obviously misses the full date/time in start and finish.
============================================
# id | username | start | finish #
============================================
# 1 | joe | 00:00 | 23:59 #
============================================
What I want to achieve is to order the results from the Timesheets table by the last_name column in the Users table with just the username that is derived the Timesheets table.
What I am trying to attempt here:
SELECT * FROM `Timesheets` WHERE `start` >= '{$monday}' AND `finish` <= '{$sunday}' ORDER BY (`Users`.`last_name` WHERE `username` = `Timesheets`.`username`) ASC
MySQL is clearly not my niche, what query would provide the desired result?
You'd have to use a JOIN and then ORDER BY, like this:
SELECT ts.*
FROM timesheets ts
JOIN users
ON ts.username = users.username
ORDER BY users.last_name
You may add the WHERE clause as required before the ORDER BY.
Use JOIN:
SELECT *
FROM Timesheets T
JOIN Users U ON T.username = U.username
WHERE T.start >= '{$monday}' AND `finish` <= '{$sunday}'
ORDER BY U.last_name ASC
use join for this:
SELECT t.*
FROM timesheets t
JOIN users
ON t.username = users.username WHERE t.start >= '{$monday}' AND t.finish <= '{$sunday}'
ORDER BY users.last_name

Combining data between three tables

I'm creating a site (For School Purpose) where you can buy stuff from different companies.
On one of the sites I want to show all the companies, but only the companies from the category and the city you have chosen.
But I also want it to be ordered by popularity.
For every time a person is buying something, the popularity of the company in the chosen category and city will be raised by 1.
The categories are: Men, Women and Family.
For this, I'm using three tables:
Table 1 - partners
| partner_id | name | type | logo |
In the first table I have the company names, type and logo.
This table is only used to get the name, type and logo from each company.
Table 2 - single_partners
| id | partner_id | address | zipcode | city |
In the second table I have all companies in the entire country.
If one compay is located multiple times in one city, there will be multiple rows, but with a different id, address, zipcode and city. The partner_id will be the same of course.
Table 3 - partner_pupolarity
| id | partner_id | men | women | family |
In the third table the popularity of each company will be.
Here each company from every city will be stored with a popularity value (men, women and family). If the company have no popularity in any of the three categories, it won't be stored in the table.
I can show each companies from each city, but I cannot sort it by popularity according to the category.
Heres is an quick example of what I want:
On the first site you can choose a category: Men, Women or Family.
When you have chosen a category, you are going to choose a city by typing the zip-code.
Then you're going to see a list where the most popular companies will be shown, sorted by the category you have chosen, and the city. If a company exist multiple times in the same city, it should only show one.
If you have chosen Men and City 1, you will se the most popular companies from the men category in City 1.
If a company do not have any popularity value from that category, it will be in the bottom of the companies.
What I can do now is only to show the companies according to the city you have chosen, but I can's sort them by popularity.
This is what I have tried:
// Load partners
$load_partners = mysql_query("SELECT * FROM partners");
while($partners = mysql_fetch_array($load_partners)) {
$partner_id = $partners['partner_id'];
$partner_name = $partners['name'];
$partner_logo = $partners['logo'];
$partner_logo_dir = "media/partners/";
$load_single_partners = mysql_query("SELECT DISTINCT '$partner_name' FROM single_partners WHERE partner_id='$partner_id' and postal='5000'");
while($single_partners = mysql_fetch_array($load_single_partners)) {
$single_partners_id = $single_partners['partner_id'];
echo '<div class="partner" style="background: url('.$partner_logo_dir.$partner_logo.'); background-size: cover;" data-partner-id="'.$partner_id.'">'.$partner_name.'
</div>'."\n";
$order_partners = mysql_query("SELECT * FROM partner_popularity WHERE partner_id = '$single_partners_id'");
while($order = mysql_fetch_array($order_partners)) {
}
}
}
I think I somehow should combine the data from the three tables but I do not know how.
..or am I doing it all wrong by using three different tables?
Hope you can understand by question :)
What you can do to achieve this is using joins : Here is some MySQL doc about this
But here, using 2 tables for single partners and popularity is not really needed, since one line of single_partners is strictly equal to one line of partner_popularty, you can put them in the same table. You should put them in the same table, and using a default of zero if the partner has no popularity registered, so it'll show last when sorting by popularity.
So, then you'll have 2 tables :
Table 1 - partners
| partner_id | name | type | logo |
Table 2 - single_partners
| id | partner_id | address | zipcode | city | pop_men | pop_women | pop_family
Now your query to select all that becomes extremely simple (just select the partners, filter the city, order them and you're done), and with a little grouping and a join, you can also select partners sorted by popularity summarized in all cities :
SELECT p.*,
SUM(pop_men) AS total_pop_men,
SUM(pop_women) AS total_pop_women,
SUM(pop_family) AS total_pop_family
FROM partners p
JOIN single_partners sp ON sp.partner_id = p.partner_id
GROUP BY partner_id
ORDER BY total_pop_men DESC,
total_pop_women DESC,
total_pop_family DESC
SELECT partners.name FROM partners, single_partners, partner_popularity
WHERE single_partners.name = 'cityname' AND partners.id = single_partners.partner_id AND
partners.id = partner_populariry.partner_id ORDER BY partner_popularity.[category]
As far as i can understand this is what your looking for, or something similar, i dont really understand the whole meaning of it, it this select you will have to do three diferent ones, one for each category.
Sorry if i didn't help.

Retrieve latest post in each category - Forum

I'm building a forum, and I have ran into a few problems.
The basic database structure looks like this:
users
| user_id | username
categories
| category_id | category_name |
forum_posts
| post_id | ref_post_id (FK) | ref_category_id (FK) | ref_user_id (FK) | post_date |
If ref_post_id is 0 that means it's the main post of the thread that have a title. For answers to a thread ref_post_id equals the main post's post_id. I hope you understand.
How would I get the latest post in each category? Including the posts thread title, and the username from user table. Should I change my table structure and add a "latest_post_id" field to categories table or something?
Very greatful for your help. I know there are similar questions, but I'm also wondering about whether I should store latest_post_id and all that in categories table or have a huge query for retrieving everything on each page load.
EDIT 2: HERE IS MY CURRENT QUERY:
SELECT category_id, name,
(SELECT COUNT(*) FROM forum_posts WHERE ref_category_id = category_id AND ref_post_id = 0) count_threads
(
SELECT title, ref_user_id, username FROM forum_posts
LEFT JOIN users ON user_id = ref_user_id
WHERE latest_post_id = (SELECT MAX(latest_post_id) FROM forum_posts WHERE ref_category_id = category_id LIMIT 1)
)
FROM forum_categories
if you have a creation date you need to get the one with the MAX date, if you don't you can use the MAX(post_id), but if you let user EDIT their post and you want to get the latest one created OR edited you should add a modification date to the database.
to get the latest post:
SELECT * FROM forum_posts p
INNER JOIN users u ON p.ref_user_id=u.user_id
WHERE `post_id`=(SELECT max(`post_id`) FROM forum_posts WHERE ref_category_id=$value);
If you are using a date, just use that field instead of post_id

Categories