How to query multiple tables and collate data - php

I am trying to make a notification list that displays notifications from multiple different content types and there respective database tables.for each content type There is a subscribe table with the respective subscriptions which I need to retrieve.the tables and there respective subscriptions tables are as follows
--------------------------
content type | subscriptions
-------------+------------
group | subscribegroup
-------------+------------
discussion | subscribediscussion
-------------+------------
forum | subscribeforum
-------------+------------
thread | subscribethread
-------------+------------
The problem I have is that each content subscription table has a different name for the id of its values eg
This is how I would get the data from one content a single table with its respective subscription table and then use UNION but isnt union heavy on the database server??
SELECT *
FROM thread t
JOIN subscribethread s ON (t.threadid = s.threadid)
WHERE userid= $currentuserid
How would I join multiple instances of other content types above with this? Thanks

We use JOIN when we need combine columns from few tables INTO ONE(or more) row. As i understand you need combine ROWS FROM DIFFERENT TABLES in one result table. There is no UNION alternative with such schemas structure.

Related

Create relational tables or store serialized data in a column?

I have a users table with this structure:
user_id | name | email | mobile
And another table called products with this structure:
product_id | name | price
now I want to add wish list to my project, so that a user can add some products into his wish list (with his favorite categories. Exmaple: add a wish list category called my favorite clothes and add product_id = 55 to that category)!
Now I have 2 options:
1. Add another colum to users table called user_wish_list and then store serialized data in that column like below:
$user_wish_list = [
'user_category_1' => ['product_id_1', 'product_id_2', ....] ;
];
and store serialize($user_wish_list) in user_wish_list column.
2. create 2 tables as below:
tabe: wish_list_categories
user_id | category_id (PK) | category_title
and
tabe: wish_list_items
category_id (FK) | item_id | product_id (FK)
and finally create a relation between these tables (By SQL join)
which option is better? I personally think the second one!
one of the reasons for my choice is that I can access to data with pure SQL query
like below (I do not have to process data after fetching from database by using unserialize() ):
SELECT users.user_id, users.name, wish_list_categories.category_id,
FROM Orders
INNER JOIN Customers ON users.user_id = wish_list_categories.category_id
But what about other advantages?
Or let me ask a more general question: when we exactly use relational tables instead of use column? (consider one-to-one relationship)
Use tables. In general, don't store structured data in individual SQL values. Let the tables and foreign keys produce the structure you need.
your tables should be like:
1- users table:
user_id|user_name|Email|price
2- products table:
product_id|product_name|category_id|price
3- products_category
category_id|category_name
4- user_wish_list table:
user_id|product_id

MySQL Selecting from two tables ordered by date

Beginner here so please go easy on me :)
So I have these two tables in my DB
Reply Table
+------------------------------------------------+
| message_id | client_id | message | date_posted |
+------------------------------------------------+
Request Table (Exactly the same)
+------------------------------------------------+
| message_id | client_id | message | date_posted |
+------------------------------------------------+
Problem:
They serve a messaging app I was testing but now I don't know how to query these tables to get all chat ordered by date from two tables. For example
Client 14 (2 hours ago): Hello there // Coming from request table
Admin (1 hour ago): Welcome // Coming from reply table
So the messages are displayed oldest first...
I tried using JOIN on clien_id since that is what I want. However, it doesn't seem to work.
I also tried selecting from a subquery containing UNION ALL, also no luck... Any ideas on how this can be done? Thanks in advance!
A union is what you're looking for. In your case, a join would combine columns from the two tables into a single row, where as you're looking to union rows from multiple tables into a single result set.
You'll want to enclose your select statements individually, and then add the order clause.
Edit: Updating this answer to include a column for the source table, as per OP's comment
(select source='reply_table', * from reply_table)
union
(select source='request_table', * from request_table)
order by date_posted desc
MySQL's docs are pretty good, and its page on unions outlines several sorting scenarios: https://dev.mysql.com/doc/refman/5.7/en/union.html
But the instruction specific to your case is:
To use an ORDER BY or LIMIT clause to sort or limit the entire UNION result, parenthesize the individual SELECT statements and place the ORDER BY or LIMIT after the last one.
select a.message
from table1 a
inner join
table2 b
on a.client_id=b.client_id
order by a.date_posted desc;

PHP function to return data from database as table with table relationships

I have a requirement for a PHP function that takes table or tables and the required columns from those db tables and returns a html table containing the data. I know how to do this for one table but am struggling with how to make this more dynamic
My thinking for one table would be to have a function that takes the table name and then an array of columns and then just selects the data from the table and then loops through it constructing the data as html and then return that from the function.
As an example my database has two tables; users and orders
users
|----------------------------|
|user_id|first_name|last_name|
|-------|----------|---------|
orders
|----------------------|
|order_id|user_id|total|
|--------|-------|-----|
Now with the function discussed above it would be easy to generate a table for all the users or orders but what I would like to do is have a function where I could dynamically join tables and for example list all users and the number of orders they've made or list all orders from user x. I know that this would be possible with many different functions but I'm really interested in developing a way of doing this dynamically and basically building all the relationships somehow in the program and then be able to call one function and request columns x,y and z
My thinking so far would be (again for this example) somehow define that number of orders for user i = count(order_id) where user_id = i
Hope this makes sense and thank you in advance
The INFORMATION_SCHEMA.KEY_COLUMN_USAGE table can be used to find all foreign key relationships from a particular table to other tables, e.g:
SELECT `TABLE_NAME`,
`COLUMN_NAME`,
`REFERENCED_TABLE_NAME`,
`REFERENCED_COLUMN_NAME`
FROM `INFORMATION_SCHEMA`.`KEY_COLUMN_USAGE`
WHERE `TABLE_SCHEMA` = SCHEMA() -- current schema
AND `REFERENCED_TABLE_NAME` IS NOT NULL
AND `TABLE_NAME` = 'orders'; -- name of table to get relationships to other tables
This should return something like the following:
+--------------+-------------+-----------------------+------------------------+
| TABLE_NAME | COLUMN_NAME | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME |
+--------------+-------------+-----------------------+------------------------+
| orders | user_id | users | user_id |
+--------------+-------------+-----------------------+------------------------+
The above can be done in PHP and the results can then be iterated over to dyamically construct a query that selects from those tables, joining on the listed columns. Will leave that part as an exercise ;-)
You wouldn't need to make a function to grab data from first table then loop around them and get data from the second table.
SQL can do this for you with 1 hit on the database.
All what you need to do is join the two tables, and grab the data you want..
If I understood what you need right, you want to grab all users id from the first table, and get their order count from the second table.
A simple join or selecting from both table could do that, and I suggest something like:
Select a.user_id, b.count(order_id)
FROM table1 as a, table2 as b
WHERE a.user_id = b.user_id
Group By a.user_id
Or you could join the tables and do a similar task.
I am assuming you're gonna access database from PHP code, so try that, and give me back your feedback.
This is easy to implement but we have to fix few things.
Our requirement:
1. Identify Tables according to column name.
2. How we can Join those tables.
3. How to resolve ambiguity of columns.
Solution:
Unique column name for each field or no table has duplicate column name.
To achieve it we should have fix table prefix for each table.
for example:
your column name could be odr_orderid and usr_orderid.
Now by identifying unique prefixes, we can identify tables.
Now issue arises how to join these tables
To resolve it:
Create an another table strong JOIN keys and JOin type Left, right,inner or full.
Thats all Now you can make the query as you want.

Getting Data from multiple tables SQLite

I have an android application that has 2 tables, one table stores posts and the other table stores images of the posts incase it has an image, changes are not all posts will have images, if a post has an image its primary key will be stored in the foreign Key table, when loading the posts I have to get all posts wether with image or not then check in the image table to see which posts have images and add the images to the posts below is a graphical overview of my tables
Post Table
`|post_id |post | post_description|
|--------|-----|-----------------|
| | | |`
Image Table
`|img_id |fk_postID | imagePath |
|--------|----------|-----------------|
| | | |`
I could have used a join like
Query = "SELECT post_id, post, post_description, imagePath FROM PostTable,
ImageTable, Where PostTable.post_id = ImageTable.fk_postID;
but this query is only returning posts with images and forgeting about posts without images, How can I get all posts be it with image or not? Thanks in advance.
ok, you asked, so give this a whirl, see if you like the output
SELECT pt.post_id, pt.post, pt.post_description, im.imagePath
FROM PostTable pt
left join ImageTable im
on im.fk_postID=pt.post_id
It will bring along for the ride the right table (ImageTable) of those posts that don't have images.
Uses table aliases (pt and im). That helps to be explicit which table the columns come from on the first line in case there are common column names in both, plus a little less typing.
Untested
reference Mysql Left Joins
Try using Left join and that will result all entries from left table and matched entries from right table.
SELECT posttable.postid,posttable.post,posttable.postdescription, imagetable.imageid,imagetable.fkpostid,imagetable.imagepath
FROM posttable
LEFT JOIN imagetable
ON posttable.postid=imagetable.fkpostid
ORDER BY posttable.postid;
Code should look like that.
http://www.w3schools.com/sql/sql_join_left.asp

Organizing a Database

In my application I have 2 tables in the DB (MySQL):
Companies and News. Company has many News.
Company can have a set of pictures which will be displayed on the company "view page" alongside with all relative information about this company.
I've added a Photos table with next fields: id company_id filename
My question is: Now I also need to have pictures which will belong to News.
I should add another table, which will be called for example Media or I should add additional field (type) to my Photos table, rename company_id to foreign_id and then filter results in PHP and build more complex queries with for example AND 'type' = 1 to fetch photos related to Company and 'type = 2' to fetch photos related to news.
What is a better approach?
You should take the company_id field out of the Photos table and create two new tables, CompanyPhotos with id, photo_id, company_id fields, and another NewsPhotos with id, photo_id, news_id.
Then if you want to get the photos for a company you can do: select * from Photos p inner join CompanyPhoto cp on p.id = cp.photo_id where cp.company_id = ?.
And similary with NewsPhoto: select * from Photos p inner join NewsPhoto np on p.id = np.photo_id where np.news_id = ?.
It is always good to normalize databases. In the beginning it was just about tables with all data and it has evoluted to linked tables with common fields.
Hence, I strongly recommend you to have the table Photos.
After all, you have to make the basic question: can a photo belong to different news? Can a news have different pictures? If both questions' answer is "yes", you have a N:M relation, which is resolved with a middle table containing an id from every table.
You could use UUIDs as your primary key. Because they are unique application-wide (if you create them with CakePHP), you could just use a parent_id column in your Photos table and get rid of the type colum.
Another approach would be MySQL Views. You could setup 2 Views (e.g. NewsPhotos, CompanyPhotos) on top of the Photos table. CakePHP handles (simple) Views like tables, so you could create easily Models & Controllers for this.

Categories