SQL duplicate row - php

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

Related

Return all wows, mached and unmatched in MySQL Query

I have two tables and i'm like to query 2 tables to obtain a report.
POSITION
+-------------+---------------+
| position_id | position_name |
+-------------+---------------+
| 1 | E1P1 |
| 2 | E1P2 |
| 3 | E3P3 |
| 4 | E4P4 |
+-------------+---------------+
PEOPLE
+------------+-------------+--------------------+
| people_id | people_name | people_position_id |
+------------+-------------+--------------------+
| 1 | JOHN | 2 |
| 2 | MARK | 4 |
+------------+-------------+--------------------+
QUERY
SELECT position_id, position_name, people_name FROM position
RIGHT JOIN people ON people_position_id = position_id
When I use simple query I get only matched rows, ho to obtain all?
I'm like to obtain this result
+----+----------+--------+
| ID | POSITION | STATUS |
+----+----------+--------+
| 1 | E1P1 | Empty |
| 2 | E1P2 | JOHN |
| 3 | E3P3 | Empty |
| 4 | E4P4 | MARK |
+----+----------+--------+
I would use a left join here:
SELECT
po.position_id,
po.position_name,
COALESCE(pe.people_name, 'EMPTY') AS STATUS
FROM position po
LEFT JOIN people pe
ON po.position_id = pe.people_position_id;
By the way, the reason your current right join attempt is failing is that you have placed the people table on the right side of the join. This means that non matching position records would be discarded. Here is my answer above, rewritten using a right join:
SELECT
po.position_id,
po.position_name,
COALESCE(pe.people_name, 'EMPTY') AS STATUS
FROM people pe
RIGHT JOIN position po
ON po.position_id = pe.people_position_id;
Note carefully that the table order has switched. Most of the time, you will see people using left joins rather than right joins.

Select foreign key (group) where is the biggest match

I have three tables group_sentences, group_sentences_attributes and group_senteces_categories.
I have an attributes array which I am using in query with IN (after implode).
Then I have one category ID because they are stored recursively, so no need for an array.
I need to select one group number where is the biggest match for $attributesArray and of course category too.
Here is table group_sentences_attributes
+-----+-------+-----------+
| id | group | attribute |
+-----+-------+-----------+
| 1 | 1 | 3564 |
| 2 | 1 | 3687 |
| 3 | 1 | 3689 |
| 4 | 2 | 3687 |
| 5 | 2 | 3564 |
+-----+-------+-----------+
Here is group_sentences_category
+-----+-------+----------+
| id | group | category |
+-----+-------+----------+
| 1 | 1 | 1564 |
| 2 | 1 | 1221 |
| 3 | 1 | 1756 |
| 4 | 2 | 1358 |
| 5 | 2 | 1125 |
+-----+-------+----------+
Here is my query, but I am afraid that it won't do the job done.
SELECT group_categories.group
FROM group_categories, group_attributes
WHERE group_categories.category = '$category'
AND group_attributes.attribute IN ($attributesArray)
GROUP BY group_categories.group
ORDER BY count(group_attributes.attribute)
Any help would be appreciated, thanks.
First, the table in your query do not match the tables in the question. I am guessing they are simply missing the "sentence". Then, you have no join clause. Simple rule: Never use commas in the from clause.
group is a lousy name for a column, because it is a keyword in SQL. The following may be what you are looking for:
SELECT gc.groupid
FROM group_sentences_attributes sa JOIN
group_sentences_category sc
ON sa.groupid = sc.groupid
WHERE sc.category = '$category' AND
sa.attribute IN ($attributesArray)
GROUP BY sa.groupid
ORDER BY count(sa.attribute);
If you only want one row, then add LIMIT 1 to the end.

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

Performing Searches over Many-to-Many Relationships

I have a database which (for the purposes of this example), has two tables that have a many to many association (with an intermediary table for holding the associations). Here is there structure:
Table A:
+-----+-------+-------+-------+
| aID | aCol1 | aCol2 | aCol3 |
+-----+-------+-------+-------+
| 1 | foo | aoo | doo |
+-----+-------+-------+-------+
| 2 | bar | aar | dar |
+-----+-------+-------+-------+
| 3 | baz | aaz | daz |
+-----+-------+-------+-------+
Table B:
+-----+-------+
| bID | bCol1 |
+-----+-------+
| 1 | alice |
+-----+-------+
| 2 | bob |
+-----+-------+
Association Table:
+-----+-----+
| aID | bID |
+-----+-----+
| 1 | 1 |
+-----+-----+
| 2 | 2 |
+-----+-----+
| 3 | 1 |
+-----+-----+
If I want to search for information by aCol2 LIKE 'aa%' AND the row has an association to bCol1 = 'bob' (i.e. resulting in only row aID = 2), how could I assemble a MySQL Query that could do something similar?
p.s. Sorry for the poor clarity, I am not exactly sure of the wording, but in a nut shell, it is about searching for data from one record that (for the purposes of this) has a 1-* relationship via a connecting table to a number of records, by information that exists in the entire set
SELECT
a.*
FROM
table_b b
INNER JOIN associations ab ON (b.b_id = ab.b_id)
INNER JOIN table_a a ON (ab.a_id = a.a_id)
WHERE
b.col_1 = 'bob'
AND a.col_2 LIKE 'aa%'
It's been awhile, but I believe this should work:
SELECT
*
FROM
A,
B,
associations
WHERE
A.aCol2 LIKE 'aa%' AND
A.aID = associations.aID AND
associations.bID = B.bID
You have to do 2 inner joins to combine the 3 tables.

Categories