Mysql user subscription query fails - php

I have a database named socialnetwork and has 5 tables category , post_category , posts , subscribe , user.
my table structures
-------- -------------
category posts
-------- ------------
categoryID postID
categoryName post
userID
categoryID
-------------- ---------------
post_category subscribe
--------------- ---------------
postID subscriberID
categoryID categoryID
--------------
usertable
--------------
userID
userName
data's in the table
category table usertable
-------------------------- -------------------
categoryID categoryName userID userName
--------------------------- --------------------
1 film 1 jijojohn32
2 television 2 sijojohn
posts_category table subscribe table
------------------ -------------------------
postID categoryID subscriberID categoryID
--------------------- ------------------------
1 1 1 1
1 2 1 2
2 2 2 2
posts table
---------------------------------------------------
postID post userID categoryID
--------------------------------------------------
1 this post is cool 1 1
2 demo post 2 2
User 1 can subscribe to different categories and he can see the articles in the categories he subscribes. That's what i am trying to implement here. And i have this query but it's not giving me the result i want.
USE socialnetwork;
SELECT socialnetwork.usertable.userName,socialnetwork.posts.post, GROUP_CONCAT(socialnetwork.category.categoryName) as category
FROM socialnetwork.category
INNER JOIN subscribe
ON subscribe.categoryID = category.categoryID
INNER JOIN posts
ON posts.categoryID = subscribe.categoryID
INNER JOIN usertable
ON usertable.userID = posts.userID
INNER JOIN socialnetwork.post_category
ON post_category.postID = posts.postID
WHERE subscriberID = "1"
GROUP BY socialnetwork.category.categoryName
Here's the result i am getting
---------------------------------
username post category
----------------------------------
jijojohn32 this post is cool film, film
sijojohn demo post television
The result i want
---------------------------------------------
username post category
-------------------------------------------
jijojohn32 this post is cool film,television
sijojohn demo post television
I want the post from the categories he subscribed to , the username of the user posted the articles , and categories which posts reside. What's wrong in my query ?. any idea ?. thanks

You are not aggregating by the right columns. I think this is the query that you want:
SELECT ut.userName, p.post, GROUP_CONCAT(c.categoryName) as category
FROM socialnetwork.category c INNER JOIN
subscribe s
ON s.categoryID = c.categoryID INNER JOIN
posts p
ON p.categoryID = s.categoryID INNER JOIN
usertable ut
ON ut.userID = p.userID INNER JOIN
socialnetwork.post_category pc
ON pc.postID = p.postID
WHERE subscriberID = 1
GROUP BY ut.userName, p.post;

Here's the working query. I made some modifications in the table. Deleted the categoryID from posts. Made a new table called post_category.
--------------
post_category
-------------
postID
categoryID
Here's the query
SELECT GROUP_CONCAT(category.categoryName) as category , category.categoryID , subscribe.subscriberID , posts.post ,
usertable.userName
from category
INNER JOIN subscribe
ON subscribe.categoryID = category.categoryID
INNER JOIN post_category
ON category.categoryID = post_category.categoryID
INNER JOIN posts
ON posts.postID = post_category.postID
INNER JOIN usertable
ON usertable.userID = posts.userID
WHERE subscriberID = 1
GROUP BY post_category.postID

There exists a conflict
Category table consists of
Category id and Category Name
Post Table consists of
Post id and Corresponding Category Id
As well as
Post_Category table consists of
Post id and Category Id
Hence it is picking from the Posts table, that
Row 1 - has only 1 category id associated with it
I suggest you remove Category id from Posttable
It is pointless to have 2 keys in 1 table, and similar 2 keys in other table.
Try to establish Primary key Foreign key relationship.
Hope that helps

Related

MySQL joining tables and returning the latest row from the second table when the comparison is made between identical values

I have table 1: users
id | name |
1 | john |
2 | garry|
3 | sam |
And table two called posts:
id | user_id | title | posted
1 | 1 | Something | 1551128761
2 | 1 | Else | 1551128761
3 | 3 | Some Title | 1551122745
4 | 2 | Demo Title | 1551129777
5 | 3 | Something | 1551126793
user_id in the second table is the id of the user in the first table
I need to get the latest post out of the table and i'm doing that currently by using this query:
SELECT u.id, u.name, p.title
FROM users AS u
LEFT JOIN posts AS p
ON p.user_id= u.id
WHERE p.posted = ( SELECT MAX(posted) FROM posts WHERE user_id = u.id )
ORDER BY u.id
LIMIT 15
But the problem with this query is that if the timestamp is the same for the same user (in this example for user with user_id 1 the timestamp is the same) i'm getting both of those rows instead of just the latest one(the latest one has the highest id)
Try this MySQL query:
SELECT u.id,
u.name,
p.title
FROM users AS u
JOIN posts AS p
ON p.id = (SELECT pi.id
FROM posts AS pi
WHERE pi.user_id = u.id
ORDER BY pi.id DESC
LIMIT 1);
Tested and works fine. Here is a demo: DBFiddle
To speed up select query, consider adding indexes
ALTER TABLE posts ADD INDEX(user_id);
ALTER TABLE posts ADD INDEX(posted);
One option using id column from posts table as following. This is assuming id is going to be different for each post record is posts table. Demo here
SELECT u.id, u.name, p.title,p.posted
FROM users AS u
LEFT JOIN posts AS p
ON p.user_id= u.id
WHERE (p.posted,p.id) = ( SELECT MAX(posted),MAX(id) FROM posts WHERE user_id = u.id )
ORDER BY u.id
How about restructuring the query slightly?
SELECT posts.title, users.id, users.name
FROM posts, users
WHERE posts.user_id = users.id
ORDER BY posts.posted DESC, posts.id DESC
LIMIT 1
Essentially selecting from posts, ordering by the posted timestamp and secondly the id of the post in descending order in case timestamp is the same.

MySQL Inner Join Merge Rows

I have the following problem: I have three tables, a users table, a categories table and a user_category table which connects the two first tables with foregn keys.
users table:
id username
1 user1
... ...
categories table:
id category
1 test1
2 test2
3 test3
... ...
user_category table
id user_id category_id
1 1 1
2 1 2
3 1 3
Now I want to select all users with their categories, but I dont want to have multiple rows of the same user - instead, I want to merge all categories of a user into one category field.
SELECT users.*, categories.category FROM user_category INNER JOIN users ON users.id = user_category.user_id LEFT JOIN categories ON categories.id = user_category.category_id
The output:
id username category
1 user1 test1
1 user1 test2
1 user1 test3
But I want the following:
id username category
1 user1 test1, test2, test3
Is there a possibility to do this?
SELECT users.id, users.username, GROUP_CONCAT(categories.category) as cats
FROM user_category
INNER JOIN users ON users.id = user_category.user_id
LEFT JOIN categories ON categories.id = user_category.category_id
GROUP BY users.id, users.username
could do what you want.
See http://www.sqlines.com/mysql/functions/group_concat
With TSQL you can use smth like How Stuff and 'For Xml Path' work in Sql Server

Cannot get data from two tables using join

First table: Product
id | Name | Price | Discount
-------------------------------
1 xyz 200
2 xyz 250
3 yz 100 50
Second table : buy
id | userid | Product_id Card_details
------------------------------------------
1 1 1 55555
2 1 2 88888
3 3 1 77777
Now i have $user_id in my php variable. If user id is 3 i want following output:
id Name Price Discount user_id Product_id Card_details
3 yz 100 50 3 1 77777
How can i achieve this.
Use JOIN or where
SELECT * FROM Product p JOIN buy b
ON p.id = b.Product_id
WHERE b.userid ='3'
SELECT * FROM Product JOIN buy ON Product.id = buy.id WHERE buy.userid = $user_id;
Try the following query
$query = "SELECT Product.id, Product.Name, Product.Price, Product.Discount,
buy.userid , buy.Product_id, buy.Card_details
FROM Product
JOIN buy ON Product.id = buy.Product_id
WHERE buy.userid = 3";
First in your Product table xyz is to time you have to use unique name for your product for better understanding.
Now in Product table id is your product id. Check your Buys tables productid there is no entry for product id 3. When you want to buy product 3 for user id 3 then buy table productid entry should be three for userid 3.
Now check the below query it will definitely work for you.
SELECT * FROM Product
INNER JOIN buy ON Product.id = buy.Product_id
WHERE buy.userid = '3';
It means you want to get product buy by userid 3.
Try This
DECLARE #USER_ID INT=3 --I/P of USER_ID
SELECT P.ID,
P.NAME,
P.PRICE,
P.Discount,
B.user_id,
B.PRODUCT_ID,
B.CARD_DETAILS
FROM #PRODUCT P
JOIN #BUY B
ON P.ID = B.ID
WHERE B.USER_ID = #USER_ID

Find uncommon data from two tables in mysql

i am using a category , product relation to find data. I am in situation like i have a category table and product table with categoryid and product type. No suppose i have a particular type and i want to find those category which a product of a specific type does not have.
Table struture are like
Category Table
____________
|Id|Category|
| 1| X |
_____________
Product Table
____________________________
|ID | Product|Category| Type|
| 1 | Y | 1 | 2 |
_____________________________
I can find it by using a sub query like
SELECT *
FROM category
WHERE id NOT IN(SELECT category
FROM product
WHERE type = 2);
Is there a way to get it by another way
I also use a JOIN like
SELECT *
FROM category AS c
JOIN products AS p
ON c.id <> p.category
WHERE p.type = 2
Why does this not give the appropriate result.
Use LEFT JOIN and use IS NULL predicate:
SELECT *
FROM category AS c
LEFT JOIN products AS p
ON c.id = p.category
AND p.type = 2
WHERE p.category IS NULL;
The unmatched rows from the second table will have null values in the category field, the WHERE p.category IS NULL will filter and give you them

Matching IDs in two different tables

I have two tables; NEWS and CATEGORIES. In the NEWS table, there is CatID field which matches with CatID table in the categories. I get the categoryID with the following code but I want to the category name of the news, not the ID. How can I pull it from the categories table?
<?php
$SQL = mysql_query("SELECT * FROM News WHERE Active = 1 ORDER BY DateEntered DESC");
while ( $Result = mysql_fetch_array($SQL)) {
$CatID[] = $Result[CatID];
$NewsName[] = $Result[NewsName];
$NewsShortDesc[] = $Result[NewsShortDesc];
}
?>
<div class="toparticle">
<span class="section"><?=$CatID[0] ?> </span>
<span class="headline"><?=$NewsName[0] ?></span>
<p><?=$NewsShortDesc[0] ?></p>
</div>
You can change your SQL query to include an inner join to get the name. To illustrate, I'm going to make the assumption that the category name column in the 'CATEGORIES' table is called 'CatName.' You can use this query:
SELECT n.*, c.CatName FROM News n
INNER JOIN Categories c ON n.CatID = c.CatID
WHERE Active = 1
ORDER BY DateEntered ASC
By what I've understood, maybe you want to do:
SELECT name FROM CATEGORIES as c, NEWS as n WHERE c.CatID = n.CatID AND n.CatID = 123
I'm a bit rusty in SQL, I think it's something like this.
From what I've understood from your question, you want to do something like this.
In the following I create 2 table for news and categories :
Table News
id| cat_id | title
1 | 1 | Test
Table Categories
id | name
1 | Horror
u can select name of category use OUTER JOIN like this
SELECT news.*, categories.name AS category_name FROM news
LEFT JOIN categories ON categories.id= news.cat_id;
if u want to know more about this outer join

Categories