MySQL query to get data from 5 tables? - php

What is the right MySQL query for this? Here's what I want to achieve.
I would like to display all status update entries, date posted, the
poster username, gender, city, and tags
I would like to display all status update entries by a member with user_id='1', the date the status update was posted, the poster username, gender, city, and tags that member has on his profile
And how can I display all the tags that the user have on their profile, in one line separated by ','? I tried group_concat earlier but i couldn't make it work. please help.
Here's my tables
STATUS_UPDATE Table
+------------------------------------------------------+
| status_id | user_id | body | postdate |
+-----------+---------+-----------------+--------------+
| 1 | 1 | hello world | Aug 12, 2012 |
+-----------+---------+-----------------+--------------+
| 2 | 1 | i miss you | Aug 13, 2012 |
+-----------+---------+-----------------+--------------+
| 3 | 2 | lorem ipsum | Aug 14, 2012 |
+-----------+---------+-----------------+--------------+
| 4 | 2 | why me? why? | Aug 14, 2012 |
+-----------+---------+-----------------+--------------+
MEMBERS Table //Primary data of members
+---------------------------------------------------+
| user_id | username | password | email |
+---------+----------+------------+-----------------+
| 1 | john_doe | qwerty | john#doe.com |
+---------+----------+------------+-----------------+
| 2 | maryjane | pass123 | mary#jane.com |
+---------+----------+------------+-----------------+
MEMBERS_DATA Table //Profile Fields
+----------------------------------------------+
| user_id | gender | description | city |
+---------+--------+---------------+-----------+
| 1 | male | i am simple | chicago |
+---------+--------+---------------+-----------+
| 2 | female | i am flirty | newyork |
+---------+--------+---------------+-----------+
MEMBERS_TAGS Table //tags that members added to their profiles
+-------------------+
| user_id | item_id |
+---------+---------+
| 1 | 555 |
+---------+---------+
| 1 | 666 |
+---------+---------+
| 1 | 7777 |
+---------+---------+
| 2 | 8888 |
+---------+---------+
TAGS Table //the info of the tags
+------------------------------+
| item_id | cat_id | name |
+---------+--------+-----------+
| 555 | 5 | sexy |
+---------+--------+-----------+
| 666 | 5 | beauty |
+---------+--------+-----------+
| 7777 | 6 | music |
+---------+--------+-----------+
| 8888 | 6 | movies |
+---------+--------+-----------+
CATEGORY Table //the category of the tags
+-------------------------+
| cat_id | category_name |
+---------+---------------+
| 5 | appearance |
+---------+---------------+
| 6 | hobbies |
+---------+---------------+
BTW I'm coding in PHP, I want to thank you in advance for the help.

SELECT
STATUS_UPDATE.* ,
MEMBERS.username ,
MEMBERS_DATA.gender ,
MEMBERS_DATA.city
TAGS.*
FROM UPDATE
LEFT JOIN MEMBERS ON MEMBERS.user_id = STATUS_UPDATE.user_id
LEFT JOIN MEMBERS_DATA ON MEMBERS_DATA.user_id = STATUS_UPDATE.user_id
LEFT JOIN MEMBERS_TAGS ON MEMBERS_TAGS.user_id = STATUS_UPDATE.user_id
LEFT JOIN TAGS ON TAGS.item_id = MEMBERS_TAGS.item_id

Related

How to join other table and count the row in laravel?

I am trying to count how many require position there are for each jobseeker.
I have two tables: jobseeker and jobposition.
jobseeker:
+----+---------+-----------+----------------+
| id | fb_name | fullname | desireposition |
+----+---------+-----------+----------------+
| 1 | John | John Cena | 3 |
| 2 | Christ | Christ | 4 |
| 3 | Thomas | Cfitcher | 2 |
+----+---------+-----------+----------------+
and jobposition:
+----+--------+------------------+
| id | job_id | require_position |
+----+--------+------------------+
| 1 | 12 | 3 |
| 2 | 13 | 3 |
| 3 | 14 | 4 |
| 4 | 15 | 5 |
| 5 | 16 | 4 |
| 6 | 17 | 3 |
+----+--------+------------------+
My expected result is:
+----+---------+-----------+----------------+-----------------------+
| id | fb_name | fullname | desireposition | total_requireposition |
+----+---------+-----------+----------------+-----------------------+
| 1 | John | John Cena | 3 | 3 |
| 2 | Christ | Christ | 4 | 2 |
| 3 | Thomas | Cfitcher | 2 | 0 |
+----+---------+-----------+----------------+-----------------------+
I want to count how many require position there for each jobseeker.
Here is what I tried using crossJoin, but am unsure which join I actually need to be using.
$jobseekers = Jobseeker::crossJoin('jobpositions')
>select('fullname','fb_name','desire_position', DB::raw('count(require_position) as total_requireposition'))
->groupBy('fullname')->paginate(10);
Can anyone help guide me? Any help would be highly appreciated.
The regular MySQL query you want is:
SELECT s.id, fullname, fb_name, desireposition, IFNULL(COUNT(require_position), 0) AS require_position
FROM jobseeker AS s
LEFT JOIN jobposition AS p ON s.desireposition = p.require_position
GROUP BY s.id
I don't use Laravel, but I think the translation would be:
$Jobseeker->select('fullname','fb_name','desire_position', DB::raw('IFNULL(COUNT(require_position), 0) as total_requireposition'))
->leftjoin('jobposition', 'desireposition', '=', 'require_position')
->groupBy('jobseeker.id')
->paginate(10)

Cross database multiple records with join in MySQL

In this case each person can be assigned to an unlimited number of companies. One of these assigned companies should always be the person's main company. As you can see in the SQL query which I have posted the ID of the person's main organization is stored in the column "main_company_id" in the "person" table.
I have database Internal on server 192.168.0.1 with Person_Company Table as given
+----+-----------+------------+------------+
| id | person_id | company_id | created_at |
+----+-----------+------------+------------+
| 1 | 1005 | 2589 | 00:00:00 |
| 2 | 1006 | 2590 | 00:00:00 |
| 3 | 1007 | 2591 | 00:00:00 |
+----+-----------+------------+------------+
Person Table is as given
+------+-------+---------+-----------------+-----------------+
| id | name | phone | main_company_id | ref_id |
+------+-------+---------+-----------------+-----------------+
| 1005 | John | 0123456 | 2590 | 273722702297768 |
| 1006 | Doe | 7894560 | 2591 | 955413080598021 |
| 1007 | Smith | 9517530 | 2589 | 164283934074454 |
+------+-------+---------+-----------------+-----------------+
Company Table is as given
+------+-----------+---------+-----------------+
| id | name | vat | ref_id |
+------+-----------+---------+-----------------+
| 2589 | Company A | 0123456 | 540603005841231 |
| 2590 | Company B | 7894560 | 725472422399397 |
| 2591 | Company C | 9517530 | 367043795528136 |
+------+-----------+---------+-----------------+
Now there is another database External on the same server 192.168.0.1 with External_Person tables as given:
+----+-----------------+-------+----------------------+--------+
| id | ref_id | name | internal_primary_key | gender |
+----+-----------------+-------+----------------------+--------+
| 1 | 273722702297768 | John | ABC123456 | male |
| 2 | 955413080598021 | Doe | BCD456789 | female |
| 3 | 164283934074454 | Smith | DEF789456 | male |
+----+-----------------+-------+----------------------+--------+
And another table on this External database is External_Company
+----+-----------------+-----------+----------------------+
| id | ref_id | name | internal_primary_key |
+----+-----------------+-----------+----------------------+
| 1 | 540603005841231 | Company A | XX4123456 |
| 2 | 725472422399397 | Company B | XX5456789 |
| 3 | 367043795528136 | Company C | XX6789456 |
+----+-----------------+-----------+----------------------+
What I want to achieve is like this result:
+----+------------+-------------+------------------+
| id | person_key | company_key | main_company_key |
+----+------------+-------------+------------------+
| 1 | ABC123456 | XX4123456 | XX5456789 |
| 2 | BCD456789 | XX5456789 | XX6789456 |
| 3 | DEF789456 | XX6789456 | XX4123456 |
+----+------------+-------------+------------------+
I have already achieved two columns through this statement:
SELECT EEP.internal_primary_key as Person_Key, EEC.internal_primary_key as Company_Key
FROM Internal.Person_Company as IPC
JOIN Internal.Person as IP on IP.id = IPC.person_id
JOIN Internal.Company as IC on IC.id = IPC.company_id
JOIN External.External_Person as EEP on IP.ref_id = EEP.ref_id
JOIN External.External_Company as EEC on IC.ref_id = EEC.ref_id
WHERE IPC.person_id = 1005;
And this has the output like this result:
+----+------------+-------------+
| id | person_key | company_key |
+----+------------+-------------+
| 1 | ABC123456 | XX4123456 |
| 2 | BCD456789 | XX5456789 |
| 3 | DEF789456 | XX6789456 |
+----+------------+-------------+
How can I get the main company's internal_primary_key of the person in this given scenario? How can I amend my this existing query to achieve the desired result which I have mentioned above?
Does this work for you? You have a lot of good work, it seems all you would need is add the EEC.internal_primary_key as main_company_key code to your select statement.
SELECT EEP.internal_primary_key as person_Key, EEC.internal_primary_key as company_Key, EEC.internal_primary_key as main_company_key
FROM Internal.Person_Company as IPC
JOIN Internal.Person as IP on IP.id = IPC.person_id
JOIN Internal.Company as IC on IC.id = IPC.company_id
JOIN External.External_Person as EEP on IP.ref_id = EEP.ref_id
JOIN External.External_Company as EEC on IC.ref_id = EEC.ref_id
WHERE IPC.person_id = 1005;
I have done this successfully after doing some research upon databases
SELECT EEP.internal_primary_key as Person_Key, EEC.internal_primary_key as Company_Key, MEEC.internal_primary_key as Main_Company_Key
FROM Internal.Person_Company as IPC
JOIN Internal.Person as IP on IP.id = IPC.person_id
JOIN Internal.Company as IC on IC.id = IPC.company_id
JOIN External.External_Person as EEP on IP.ref_id = EEP.ref_id
JOIN External.External_Company as EEC on IC.ref_id = EEC.ref_id
JOIN Internal.Company as MIC on MIC.id = IP.main_company_id
JOIN External.External_Company as MEEC on MIC.ref_id = MEEC.ref_id
WHERE IPC.person_id = 1005;
And now this results as I wanted:
+----+------------+-------------+------------------+
| id | person_key | company_key | main_company_key |
+----+------------+-------------+------------------+
| 1 | ABC123456 | XX4123456 | XX5456789 |
| 2 | BCD456789 | XX5456789 | XX6789456 |
| 3 | DEF789456 | XX6789456 | XX4123456 |
+----+------------+-------------+------------------+

Merge and replace table id with name of two table SQL

table customers:
+----+------------+
| id | text |
+----+------------+
| 33 | name1 |
| 34 | name2 |
| 35 | name3 |
| 36 | name4 |
+----+------------+
table orders:
+----+--------+------------+----------+
| id | cid | ordername | colors |
+----+--------+------------+----------+
| 8 | 34 | name | 5 |
+----+--------+------------+----------+
Is possible with one query have this result?
+----+--------+------------+----------+
| id | cid | ordername | colors |
+----+--------+------------+----------+
| 8 | name1 | name | 5 |
+----+--------+------------+----------+
here how you can do it
select o.`id`, `text` as cid , `ordername`, `colors` from orders o
inner join customers c
on c.id = o.cid
DEMO HERE
OUTPUT:
ID CID ORDERNAME COLORS
8 name2 name 5

Display 2 filtered columns from 2 tables in PHP

I have 2 tables - users and users_audit, need to display results from 2 separate queries into 2 columns with relation to each other. I already figured out both queries.
query for users: SELECT rowid,data FROM users WHERE columnid = 1 GROUP BY rowid;
+-------+------------+
| rowid | data |
+-------+------------+
| 1 | John |
| 2 | Abi |
| 3 | Tony |
| 4 | Gregg |
| 5 | Jon |
| 6 | Victor |
| 7 | Daniel |
query for users_audit: SELECT date_created FROM users_audit WHERE rowid = 6 ORDER BY date_created DESC, date_created DESC LIMIT 1;
Purpose of the query is to display latest date_created for particular rowid.
+---------------------+
| date_created |
+---------------------+
| 2012-07-04 09:20:12 |
+---------------------+
Table users_audit looks like this:
SELECT * FROM users_audit;
+-------+---------+--------------+-------------+---------------------+
| id | rowid | before_value | after_value | date_created |
+-------+---------+--------------+-------------+---------------------+
| 1 | 6 | 3 | 5 | 2012-06-29 15:48:11 |
| 2 | 5 | Out (0) | 2 | 2012-07-04 09:20:10 |
| 3 | 6 | 5 | 4 | 2012-07-04 09:20:12 |
| 4 | 7 | 3 | 6 | 2012-07-04 09:20:14 |
| 5 | 3 | 2 | 3 | 2012-07-04 09:20:16 |
| 6 | 15 | 6 | 5 | 2012-07-04 09:20:22 |
I need to display 2 columns - data from users and date_created from users_audit for each rowid. It means query for users_audit must be run for each rowid (in the loop?).
Expected result displayed in php is:
+------------+----------------------+
| data | date_created |
+------------+----------------------+
| John | (latest date) |
| Abi | (latest date) |
| Tony | (latest date) |
| Gregg | (latest date) |
| Jon | (latest date) |
| Victor | 2012-07-04 09:20:12 |
| Daniel | (latest date) |
How can this be achieved this in php?
Why cant you just create a view and use a join to create the table you want?
SELECT users.data, users_audit.date_created FROM users
INNER JOIN users_audit ON users.rowid = users_audit.rowid
Or am I missing something here?
EDIT
SELECT users.data, users_audit.date_created FROM users
INNER JOIN users_audit ON users.rowid = users_audit.rowid
WHERE users_audit.date_created = (SELECT MAX(date_created) from users_audit
GROUP BY rowid)
I believe this should work..? Let me know.

SQL statement to show difference between every user choice and one user choice

Basically I need to create output TOP table where users are arranged by comparing their points with admin's points.
For example:
User3 | 0 //Everything was as admin had.
User5 | 3 //One song had 2 points different from admin and one was off by one
ect.
In my database I have three tables:
Table: rating
+------------+---------+----------+---------+
| rating_id | user_id | song_id | points |
+------------+---------+----------+---------+
| 1 | 1 | 4 | 0 |
| 2 | 1 | 3 | 1 |
| 3 | 3 | 2 | 3 |
| 4 | 4 | 2 | 2 |
| 5 | 2 | 1 | 4 |
Table: songs
+---------------+------------+
| song_name_id | song_name |
+---------------+------------+
| 1 | Song1 |
| 2 | Song2 |
| 3 | Song3 |
| 4 | Song4 |
| 5 | Song5 |
Table: users
+----------+----------+----------+
| id | username | password |
+----------+----------+----------+
| 1 | User1 | passw |
| 2 | User2 | wordp |
| 3 | User3 | somet |
| 4 | User4 | hings |
It should be something like this (not in any programming language):
Compare user_id > 1 with user_id=1 //Let's say that the comparable admin is user_id=1
$result= ABS(user.points-admin.points)++;
And put this to array as:
username => result
Then when I sort this array by result, I can print it as top table - who got the closest result to admin!
I tryed several different solutions but never got the right result.
Can anybody help me?
UPDATE:
Thanks!
With JOIN the result is:
+------------+---------+----------+---------+-----------+
| song_id |song_name| user_id |username |rating_diff|
+------------+---------+----------+---------+-----------+
| 1 | Song1 | 1 | admin | 0 |
| 2 | Song2 | 1 | admin | 0 |
...etc...
With LEFT JOIN the result is:
+------------+---------+----------+---------+-----------+
| song_id |song_name| user_id |username |rating_diff|
+------------+---------+----------+---------+-----------+
| 1 | Song1 | 11 | user2 | NULL |
| 1 | Song1 | 10 | user1 | NULL |
| 1 | Song1 | 12 | user3 | NULL |
| 1 | Song1 | 1 | admin | 0 |
| 2 | Song2 | 11 | user2 | NULL |
| 2 | Song2 | 10 | user1 | NULL |
| 2 | Song2 | 12 | user3 | NULL |
| 2 | Song2 | 1 | admin | 0 |
..etc..
So.. Something is wrong, the rating_diff does not work.
Assuming you want this comparison on a song-by-song basis (instead of a total or average across all songs), try:
select r.song_id,
s.song_name,
r.user_id,
u.username,
abs(r.points - r1.points) rating_diff
from rating r
join songs s on r.song_id = s.song_name_id
join users u on r.user_id = u.id
join rating r1 on r.song_id = r1.song_id and r1.user_id = 1
order by s.song_name, abs(r.points - r1.points)
This should sort the output by the song name, and then by the difference between the admin's points and the users' points. (Change the join on rating r1 to be a left join if you can't guarantee an admin rating for every song.)

Categories