query specific table based on search keyword in mysql - php

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%';

Related

Select from table where count from another related table is only one

I've tow tables both are related by id ... I want a single query using eloquent or mysql statements to do below ... :
clients
-----------
| Id | name |
-----------
| 1 | name1|
-----------
| 2 | name2|
-----------
| 3 | name3|
-----------
requests
----------------
| Id | client_id |
----------------
| 1 | 1 |
----------------
| 2 | 1 |
----------------
| 3 | 2 |
----------------
| 4 | 3 |
----------------
| 5 | 3 |
----------------
I just want the result to show just clients that has only one request
result
----------------
| Id | name |
----------------
| 2 | name2 |
----------------
How to make it in mysql or laravel elequent ????
You can try the following
DB::table('requests')->groupBy('client_id')->havingRaw('COUNT(*) = 1')->get();
Assuming you have working eloquent Models and relationships you could do:
Client::has('requests', '=', 1)->get();
The next query should resolve your problem:
SELECT
clients.Id,
clients.name
FROM requests
JOIN clients ON clients.Id = requests.client_id
GROUP BY clients.Id, clients.name
HAVING COUNT(*) = 1
;

MySql query on two table

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.

How to count number of rows with the same column data and display to table?

I have 2 tables, the 'department' and 'document'.
Table department
| doc_id | dept_name |
----------------------------------
| 1 | Information Technology|
| 2 | Software Development |
| 3 | Human Resource |
| 4 | Accounting |
| 5 | Support |
Table document
| doc_id | doc_name | author | description | department |
----------------------------------------------------------------------------
| 1 | Maps | User1 | sample | Information Technology |
| 2 | Audits | User3 | sample | Software Development |
| 3 | Image | User1 | sample | Information Technology |
| 4 | Papers | User4 | sample | Human Resource |
| 5 | Print Screen| User1 | sample | Software Development |
| 6 | Transaction | User3 | sample | Accounting |
| 7 | Graph | User1 | sample | Support |
| 8 | Excel | User1 | sample | Information Technology |
Now, I want to display the table with two columns: department and total_doc.
Output:
| department |total_doc|
-----------------------------------
| Information Technology| 3 |
| Software Development | 2 |
| Human Resource | 1 |
| Accounting | 1 |
| Support | 1 |
I want to display the total document inside the department and arrange them in ascending order.
Here's my query.(not sure)
SELECT department, count(doc_name) as 'total_doc' FROM tbl_document GROUP BY doc_name
I'm using MVC pattern in Codeigniter.
$this->db->select("department, count(doc_name) as 'total_doc'");
$this->db->from('document');
$this->db->group_by('doc_name');
Also, How can I display this in table? like using foreach in html?
You need to do group by with department not with doc_name.
$this->db->select("department, count(doc_name) as 'total_doc'");
$this->db->from('document');
$this->db->group_by('department');
$result = $this->db->get()->result();
Hope This will help you.
foreach ($result as $row)
{
echo $row->department."----".$row->total_doc;
}
here you go
SELECT dept_name,COUNT(td.department) FROM department d
LEFT JOIN tdocument td ON td.`department`=d.`dept_name`
GROUP BY td.`department` ORDER BY COUNT(td.`department`) DESC;
You want one line per department. IN SQL words: You want to group by department.
select department, count(*) as total_doc from document group by department;
(BTW: don't use single quotes for column aliases.)

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 ...

How To Copy Database Records and Track Their New IDs

I have three tables: years, employees, positions. Suppose that I already have these data in those tables.
years:
----------------
| id | name |
----------------
| 1 | 2011 |
----------------
positions:
------------------------------
| id | name | year_id |
------------------------------
| 1 | Director | 1 |
| 2 | Manager | 1 |
------------------------------
employees:
---------------------------------------------------------
| id | name | position_id | year_id |
---------------------------------------------------------
| 1 | Employee A (Director) | 1 | 1 |
| 2 | Employee B (Manager) | 2 | 1 |
---------------------------------------------------------
========================================
The years table is a central point.
If I insert a new year record, I must also copy all positions and employees which are related to the previous year.
So if I insert year 2012 into the years table, the data is suppose to be like this:
years:
----------------
| id | name |
----------------
| 1 | 2011 |
| 2 | 2012 |
----------------
positions:
------------------------------
| id | name | year_id |
------------------------------
| 1 | Director | 1 |
| 2 | Manager | 1 |
| 3 | Director | 2 |
| 4 | Manager | 2 |
------------------------------
employees:
---------------------------------------------------------
| id | name | position_id | year_id |
---------------------------------------------------------
| 1 | Employee A (Director) | 1 | 1 |
| 2 | Employee B (Manager) | 2 | 1 |
| 3 | Employee A (Director) | 3 (?) | 2 |
| 4 | Employee B (Manager) | 4 (?) | 2 |
---------------------------------------------------------
NOTICE the question marks in the third and fourth row of employees table.
I use these queries to insert a new year and copy all related positions and employees:
// Insert new year record
INSERT INTO years (name) VALUES (2012);
// Get last inserted year ID
$inserted_year_id = .......... // skipped
// Copy positions
INSERT INTO positions (name, year_id) SELECT name, $inserted_year_id AS last_year_id FROM positions WHERE year_id = 1;
// Copy employees
INSERT INTO employees (name, position_id, year_id) SELECT name, position_id, $inserted_year_id AS last_year_id FROM employees WHERE year_id = 1;
The problem is at copying employees query. I can't find a method to get or track the new ID of positions.
Is there a simple method to do this?
Thank you very much.
Your data model is seriously flawed and probably needs a complete overhaul, but if you insist on copying the data like you describe, this should do the trick:
// Copy employees
INSERT INTO employees (name, position_id, year_id)
SELECT name, new_positions.id, $inserted_year_id AS last_year_id
FROM employees
JOIN positions AS old_positions ON old_positions.id = employees.position_id
AND old_positions.year_id = employees.year_id
JOIN positions AS new_positions ON new_positions.name = old_positions.name
AND new_positions.year_id = $inserted_year_id
WHERE employees.year_id = 1
I think you should read about database normalization. Copying the data leads to maintenance issues and erroneous reporting.
If you went with a different design like the following, then there would be nothing to insert, until an employee changes position, is terminated, or a position is discontinued. There are plenty of other ways to approach this, too, but you should minimize redundancy (i.e. have only one copy of each Employee), and then keep track of data that changes over time, separately. Also read about foreign keys before you try to implement something like this.
positions:
-- If you are keeping track of the years that each position is active,
-- using dates provides simplicity. Note: this design assumes that positions
-- are never reactivated after being deactivated.
------------------------------------------------
| id | name | DateActive | DateInactive |
------------------------------------------------
| 1 | Director | 01/01/2011 | |
| 2 | Manager | 01/01/2011 | |
------------------------------------------------
employees:
---------------------------------------------------------------
| id | name | DateHired | DateTerminated |
---------------------------------------------------------------
| 1 | Employee A | 01/01/2011 | |
| 2 | Employee B | 01/01/2011 | |
| 3 | Employee C | 01/01/2011 | 10/01/2012 |
---------------------------------------------------------------
EmployeePositionRelationships
--If you are keeping track of time that each employee held a position
-- Employee A has been a Director since 1/1/2011
-- Employee B was a Manager from 1/1/2011 to 10/6/2012. Then they became a Director
-- Employee B was a Manager from 1/1/2011 to 10/1/2012. Then they were terminated
--------------------------------------------------------
EmployeeId | PositionId | DateStarted | DateEnded |
--------------------------------------------------------
1 | 1 | 01/01/2011 | |
2 | 2 | 01/01/2011 | 10/6/2012 |
3 | 2 | 01/01/2011 | 10/1/2012 |
2 | 1 | 10/6/2012 | |
--------------------------------------------------------

Categories