MySql query on two table - php

I have two table 'users' and 'friends' I am having difficulty joining them
users table
id | name | usercode
--------------------
1 | david | 2WM
2 | Samme | E5N
3 | Awudu | C0Q
4 | John | VX6
5 | Jerem | FG3
Friends Table
id | actor | target
--------------------
1 | E5N | FG3
2 | 2WM | VX6
3 | FG3 | 2WM
4 | C0Q | VX6
5 | FG3 | VX6
Basically i want to select all users from USERS table who has 'FG3' in either target or actor column in the FRIENDS table.
The result will be
id | name | usercode | actor | target
--------------------------------------
2 | Samme | E5N | E5N | FG3
1 | david | 2WM | FG3 | 2WM
5 | John | VX6 | FG3 | VX6
I have triend everything i know but still i am not getting the correct results
I will be glad if anyone can help me since I need to present this work tomorrow morning. Thank you

Looks like you want to join on usercode equals actor or target, then put the 'FG3' part in a WHERE clause:
SELECT users.id, users.name, users.usercode, friends.actor, friends.target
FROM users
INNER JOIN friends
ON users.usercode = friends.actor OR users.usercode = friends.target
WHERE users.usercode != 'FG3'
AND (friends.actor = 'FG3' OR friends.target = 'FG3');
Using INNER JOIN limits your query to only records that exist in both tables.

Related

How to check if 2 values IS NULL

I have these tables...
GROUP_MEMBERS
+---------------------------------+
| id | group_id | member_id |
+---------------------------------+
| 1 | 1 | 1 |
| 2 | 1 | 4 |
+---------------------------------+
MEMBERS
+-------------------------------------+
| id | first | last | role_id |
+-------------------------------------+
| 1 | Jack | Jones | 1 |
| 2 | Jane | Doe | 2 |
| 3 | Bob | Bee | 2 |
| 4 | Jen | Nee | 1 |
+-------------------------------------+
GROUPS
+-----------------+
| id | name |
+-----------------+
| 1 | group1 |
| 2 | group2 |
+-----------------+
As it is, I am using the following query...
SELECT
(members.id) AS memid,
members.first,
members.last,
members.role_id
FROM
members
LEFT JOIN group_members ON
members.id = group_members.member_id
WHERE
group_members.member_id IS NULL
GROUP BY
members.id;
This outputs the members (Jane and Bob) who are not in the 'GROUP_MEMBERS' table as it should, but what I am trying get working is if I am on and another group ($_GET['group_id']), how can I show all members that do not have rows that match group_id and member_id on the 'GROUP_MEMBERS' table...
i.e if group_id = '2' show all members
I have tried adding in WHERE clause... AND group_members.group_id IS NULL.. but it shows nothing then.
Does anyone have a query which would get the output I'm looking for?
Thanks
[EDITED]
Just to clarify...
If my url had 'group_id=1'
I should see:
Bob
Jane
If my url has 'group_id=2'
I should see:
Jack
Jane
Bob
Jen
So it only shows 'members' that do not exist( with the 'group_id' in the url) in the 'GROUP_MEMBERS' table
If I have understood the question correctly, you are looking for something like I have made on this fiddle:
DB Fiddle
The query I use is:
$sql = 'SELECT * FROM groups
RIGHT JOIN group_members ON groups.id = group_id
RIGHT JOIN members ON member_id = members.id
WHERE group_id <> ? OR group_id is NULL;'
$group_id = $_GET['group_id'];
$query = $mysqli->prepare($sql);
$query->bind_param('i', $group_id);
In short, this query will select from the groups table, ensuring that we will select every group in your database.
Then we will join the other two tables completely (using the RIGHT JOIN).
Finally, we are going to select every member that isn't the specified the one provided by the URL, or any member that is not in a group.
You can use a sub-query
how can I show all members that do not have rows that match 'group_id'
$group_id= $_GET['group_id'];
$q = "SELECT * FROM MEMBERS WHERE MEMBERS.id NOT IN(
SELECT member_id FROM GROUP_MEMBERS WHERE group_id='$group_id'
);";
Explanation
SELECT member_id FROM GROUP_MEMBERS WHERE group_id='$grID'
this will get all the members in this group by a given ID
then you select all members that are not among them.
SELECT * FROM MEMBERS WHERE MEMBERS.id NOT IN()
this one will give members data except the ids inside the brackets
the sub query will get the ids of members in a given group
no need for joining the three tables since you are using id of the group existing in GROUP_MEMBERS and linking the GROUP and MEMBERS
one side note
if you have a group name and what all users not in this group you then will need to use the GROUPS table
SELECT * FROM MEMBERS WHERE MEMBERS.id NOT IN(
SELECT member_id FROM GROUP_MEMBERS WHERE group_id = (
SELECT id from GROUPS WHERE name = '$Group_Name'
)
);
you may use WHERE group_id IN (...) it will work the same
This is a demonstration, I created same database with same data and tested the queries
+----+-------+-------+---------+
| id | first | last | role_id |
+----+-------+-------+---------+
| 1 | Jack | Jones | 1 |
| 2 | Jane | Doe | 2 |
| 3 | Bob | Bee | 2 |
| 4 | Jen | Nee | 2 |
+----+-------+-------+---------+
+----+--------+
| id | name |
+----+--------+
| 1 | group1 |
| 2 | group2 |
+----+--------+
+----+----------+-----------+
| id | group_id | member_id |
+----+----------+-----------+
| 1 | 1 | 1 |
| 2 | 1 | 4 |
+----+----------+-----------+
I run the sub-query as above and the results as expected,
MariaDB []> select * from members where id not in
(select member_id from group_members where group_id = 1);
+----+-------+------+---------+
| id | first | last | role_id |
+----+-------+------+---------+
| 2 | Jane | Doe | 2 |
| 3 | Bob | Bee | 2 |
+----+-------+------+---------+
similar for when you have group name
MariaDB []> select * from members where id not in
(select member_id from group_members where group_id =
(select id from groups where name='group1'));
+----+-------+------+---------+
| id | first | last | role_id |
+----+-------+------+---------+
| 2 | Jane | Doe | 2 |
| 3 | Bob | Bee | 2 |
+----+-------+------+---------+

MySQL join, return 1 row from one table and multiple rows from another table as an array or list

I am working on a project to catalogue laptops and as such am trying to re-use as much information as possible. A simplified version of the MySQL tables are:
Table: laptop
|----------------------------------|
| id | make | line | model |
| 1 | 1 | 1 | Late 2015 13" |
|----------------------------------|
Table: make
|----------------------------------|
| id | name | other info |
| 1 | Apple | |
|----------------------------------|
Table: line
|----------------------------------|
| id | name | other info |
| 1 | MacBook Pro | |
|----------------------------------|
Table: networking
|----------------------------------|
| id | name | other info |
| 1 | A wifi card | |
| 2 | Another card | |
| 3 | Yet another | |
|----------------------------------|
Table: laptop_networking
|----------------------------------|
| id | networking | laptop |
| 1 | 3 | 1 |
| 2 | 1 | 1 |
|----------------------------------|
So far I used the current statement to retrieve the data in PHP
$statement = $dbc->prepare("
SELECT l.id
, m.id AS makeID
, m.name AS makeName
, n.id AS lineID
, n.name AS lineName
, l.model
FROM laptop l
JOIN make m
ON l.make = m.id
JOIN line n
ON l.line = n.id
WHERE l.id = :laptop);
$statement->bindParam(':laptop', $anID, PDO::PARAM_INT);
$statement->execute();
$theLaptop = $statement0>fetch();
At present running this code with $anID = 1 returns
|---------------------------------------------------------------|
| id | makeID | makeName | lineID | lineName | Model |
| 1 | 1 | Apple | 1 | MacBook Pro | Late 2015 13" |
|---------------------------------------------------------------|
What I would like to do is append another column to the table which returns all names from Networking which have an ID equal to a row in laptop_networking where the laptop field is equal to the ID from the retrieved laptop row
Such as:
|------------------------------------------------------------------------------------------|
| id | makeID | makeName | lineID | lineName | model | networking |
| 1 | 1 | Apple | 1 | MacBook Pro | Late 2015 13" | Yet another, A wifi card |
|------------------------------------------------------------------------------------------|
Is this possible as my many attempts at different types of JOINs have not yielded the desired results.
Thank you
Try this query:
SELECT laptop.id,
make.id AS makeID,
make.name AS makeName,
line.id AS lineID,
line.name AS lineName,
laptop.model,
t.networking
FROM laptop
INNER JOIN make
ON laptop.make = make.id
INNER JOIN line
ON laptop.line = line.id
INNER JOIN
(
SELECT t1.laptop, GROUP_CONCAT(t2.name) AS networking
FROM laptop_networking t1
INNER JOIN networking t2
ON t1.networking = t2.id
GROUP BY t1.laptop
) t
ON laptop.id = t.laptop
WHERE laptop.id = :laptop
Demo here:
Rextester

SQL: get data spread over 3 tables

I am trying to get some statistics for an online game I maintain. I am searching for an SQL statement to get the result on the bottom.
There are three tables:
A table with teams, each having a unique identifier.
table teams
---------------------
| teamid | teamname |
|--------|----------|
| 1 | team_a |
| 2 | team_x |
---------------------
A table with players, each having a unique identifier and optionally an affiliation to one team by it's unique teamid.
table players
--------------------------------
| playerid | teamid | username |
|----------|--------|----------|
| 1 | 1 | user_a |
| 2 | | user_b |
| 3 | 2 | user_c |
| 4 | 2 | user_d |
| 5 | 1 | user_e |
--------------------------------
Finally a table with events. The event (duration in seconds) is related to one of the players through their playerid.
table events.
-----------------------
| playerid | duration |
|----------|----------|
| 1 | 2 |
| 2 | 5 |
| 3 | 3 |
| 4 | 8 |
| 5 | 12 |
| 3 | 4 |
-----------------------
I am trying to get a result where the durations of all team members is summed up.
result
--------------------------
| teamid | SUM(duration) |
|--------|---------------|
| 1 | 14 | (2+12)
| 2 | 15 | (3+8+4)
--------------------------
I tried several combinations of UNION, WHERE IN, JOIN and GROUP but could not get it right. I am using PostgreSQL and PHP. Can anyone help me?
Just use sum with group by:
select t.teamid, sum(e.duration)
from team t
join players p on t.teamid = p.teamid
join events e on p.playerid = e.playerid
group by t.teamid
If you need all teams to be returned even if they don't have events, then use an outer join instead.
Try this
SELECT teamid, Sum(duration),
AS LineItemAmount, AccountDescription
FROM teams
JOIN teams ON teams.teamid = players.teamid
JOIN events ON players.playersid = events.playersid
JOIN GLAccounts ON InvoiceLineItems.AccountNo = GLAccounts.AccountNo
GROUP BY teamid
http://www.w3computing.com/sqlserver/inner-joins-join-two-tables/

query specific table based on search keyword in mysql

I am creating a search portal in PHP from which user can search for a specific cuisine. In MySQL I have multiple tables for each cuisine and the respective hotel names that offer the cuisine. For example, in table
How can I query a specific cuisine table based on the cuisine search keyword?
So if a user enters 'mexican' as the search query, how can it connect to the 'Table2 - Mexican' and return the hotel names from this table?
Table1 - Chinese
_______________________
| id | hotelname |
|______|______________|
| 1 | hotel1 |
| 2 | hotel2 |
| 3 | hotel3 |
| 4 | hotel4 |
| 5 | hotel5 |
|______|______________|
Table2 - Mexican
_______________________
| id | hotelname |
|______|______________|
| 1 | hotel1 |
| 2 | hotel2 |
| 3 | hotel3 |
| 4 | hotel4 |
| 5 | hotel5 |
|______|______________|
Table3 - Pizza
_______________________
| id | hotelname |
|______|______________|
| 1 | hotel1 |
| 2 | hotel2 |
| 3 | hotel3 |
| 4 | hotel4 |
| 5 | hotel5 |
|______|______________|
Your database concept is very unflexible. I think you should put the cuisines into your database as information (i.e. table content) instead of metadata describing single tables. Tables should generally considered to be static just like the code you write to access the database and its tables. If you implement the cuisines as different tables you would have to hardwire every cuisine into your code.
Here is a suggestion for a better approach:
Create a hotels table to store all the hotels,
Create a cuisines table to store all the different types of cuisines,
Make an additional table to establish the n:m relationship between the hotel and the cuisine.
Example:
hotels: id, name, address, city, telno, email
cuisine: id, name, description
rel: cuisine, hotel (where both are the foreign keys to the
id columns of the respective tables above)
See also:
How to handle a Many-to-Many relationship with PHP and MySQL.
MySQL: Many To Many Relationships ยป Return True
You might want to check this question to create a many-to-many relationship:
many-to-many and many-to-many intersections
I guess what you would like to achieve is something like this:
Table1 - Hotel
_______________________
| id | hotelname |
|______|______________|
| 1 | hotel1 |
| 2 | hotel2 |
| 3 | hotel3 |
| 4 | hotel4 |
| 5 | hotel5 |
|______|______________|
Table2 - Cuisine
____________________________________________
| id | cuisine_name | keywords |
|______|______________|____________________|
| 1 | Chinese | Shandong,Noodles,. |
| 2 | Mexican | Tacos,Beans,... |
| 3 | Itarian | Pizza,Pasta,.. |
|______|______________|____________________|
Table3 - HotelCuisine
___________________________________
| id | hotel_id | cuisine_id |
|______|____________|______________
| 1 | 1 | 2 |
| 2 | 1 | 3 |
| 3 | 2 | 1 |
| 4 | 2 | 2 |
| 5 | 3 | 3 |
|______|____________|_____________|
SQL:
SELECT hotelname, cuisine_name FROM Hotel
INNER JOIN HotelCuisine ON Hotel.id = HotelCuisine.hotel_id
INNER JOIN Cuisine ON Cuisine.id = HotelCuisine.cuisine_id
WHERE keywords like '%pizza%'
Result:
________________________________________
| hotelname | cuisine_name |
|_______________|______________________|
| hotel1 | Itarian |
| hotel3 | Itarian |
|_______________|______________________|
DEMO: http://sqlfiddle.com/#!2/961de/1
Hope this helps
you can check SQL UNION. But instead of having multiple tables with the same fields, you can try normalization to minimize the redundancy and to make queries easier.
Something like:
Hotel Table
-----------------------------
id | hotelname | categoryID
------------------------------
1 | hotel name 1 | 1
2 | hotel name 2 | 2
-----------------------------
Category Table
-------------------
id | categoryname
-------------------
1 | chinese
2 | mexican
------------------
And query as simple as:
SELECT a.hotelname, b,categoryname
FROM hotel_table a
LEFT JOIN category_table b
ON a.categoryID = b.id AND b.categoryname LIKE '%mexican%';

SQL duplicate row

I have a big filter with many options and want to generate the query for sql automaticle and without many code.
GET:
searchvalue=abc
&title=abc
&description=abc
&category=1
&subcategory=2
&zip=7
&city=ke
&country=DE
SQL:
SELECT activity.* FROM activity,subcategory,city,country
WHERE activity.title LIKE '%abc%' OR activity.description LIKE '%abc%'
AND subcategory.SubID = 2
AND city.zip LIKE '%7%'
AND city.City LIKE '%ke%'
AND country.CShort= 'DE'
With this options, I have 1 row in my database.
The answer is this row many times, many many times.
I know that the sql duplicate a row, when a table is not used in a WHERE clausel - but why he do it now and how can I solve that?
Edit: I have a ER, but the database is in german (school project), maybe it help you to understand:
Thanks!
You are doing a cross product by selecting multiple tables. SQL will return every row from the one table combined with every row in the other table.
For example in a database with table a
|------|----------|
| idA | textA |
|------|----------|
| 1 | fooA |
| 2 | barA |
|------|----------|
and table b
|------|----------|
| idB | textB |
|------|----------|
| 1 | fooB |
| 2 | barB |
|------|----------|
when you do
SELECT * FROM a, b
you would get
|------|----------|------|----------|
| idA | textA | idB | textB |
|------|----------|------|----------|
| 1 | fooA | 1 | fooA |
| 1 | fooA | 2 | barA |
| 2 | barA | 1 | fooB |
| 2 | barA | 2 | barB |
|------|----------|------|----------|
To combine these rows logically you do a JOIN. That means you tell in your query which rows belong together. You can do so by JOIN clause or without JOIN clause directly in the WHERE clause.
Back to the example you would do
SELECT * FROM a, b
WHERE a.idA = b.idB
-- or
SELECT * FROM a
JOIN b ON a.idA = b.idB
you would get only 2 rows.
|------|----------|------|----------|
| idA | textA | idB | textB |
|------|----------|------|----------|
| 1 | fooA | 1 | fooA |
| 2 | barA | 2 | barB |
|------|----------|------|----------|
To answer your question:
You have to support JOIN/WHERE clauses to connect your tables activity, subcategory, city and country according to your database schema.
I don't know your table structures but for example clauses like this:
WHERE
...
AND city.country_id = country.id
AND activity.subcategory_id = subcategory.id
AND ...

Categories