Searching multiple tables in query - php

SELECT DISTINCT business.name AS businessname
,business.description AS description
FROM business
, category
, sub_categories
WHERE business.cityID = '$city'
AND (category.name LIKE '%$name%'
OR sub_categories.name LIKE '%$name%')
AND business.status = 0
Pls the above SQL code is suppose to search a set of two tables the ones in the bracket and return the result, but for some reason, it's not doing so. What am i doing wrong?
Thank You.

Your query would produce a cartesian product. Depending on the size of your tables that could take a considerable amount of time.
Based on your clarification I'd use a subquery to check for matching categories, this way you don't have to use distinct in your query as it would only return each business once. I also suggest you to start with a decent SQL tutorial.
SELECT name AS businessname
,description AS description
FROM business
WHERE cityID = '$city'
AND status = 0
AND ( categoryID in (select id from category where name like '%$name%')
or subcategoryID in (select id from sub_categories where name like '%$name%')
)

Two things come to mind:
You are not joining any of the three tables together. Consider adding a few LEFT JOIN clauses.
You are selecting columns from only one table. If you wanted columns from other tables, you should add them to your SELECT clause.

Related

MySQL Query Involving 3 Tables And 2 Databases, Can't Get Correct Columns

I'm using the following query to pull data from 3 tables. 2 are in the same database and 1 in a different database. Basically I have recipes in one table, and I'm using the recipieToCountry table to connect to the countries table so I know what country a recipe belongs to.
$contentQuery = $page->dbf->query("
SELECT *
FROM recipes, recipeToCountry, content.countries
WHERE recipes.id = recipeToCountry.recipeId
AND recipeToCountry.countryId = content.countries.id
AND content.countries.origId = '$country'
");
The problem I'm running into is when I call $content->title it returns the title from countries when I want the title from recipies. My understanding is SELECT * is the issue, so I tried to change the query to this:
SELECT title, description, approved, active, id, recipeId, countryId
FROM recipes, recipeToCountry
WHERE recipes.id = recipeToCountry.recipeId
UNION
SELECT id, origId, null, null, null, null, null
FROM content.countries
WHERE content.countries.origId = 1
AND recipeToCountry.countryId = content.countries.id
Unfortunately this query has an error, and I'm unsure how to fix it. When I removed the last AND the UNION doesn't seem to work as well. Any ideas on what changes I could make to get the correct columns?
Simple JOINs should work well:
select r.*, c.*
from recipes r
join repiceToCountry rc on r.id = rc.recipeId
join content.countries c on c.id = rc.countryId
where c.origId = '$country'
You must make sure you have SELECT privileges on the other database.
Also, you can replace r.*, c.* by the specific columns you want to show.
I developed a habit a long time ago of always putting the table alias/name before every field in the query. This way you can modify the query later on without worrying about fields names that conflict when you add tables to the query. I also prefer joins to multiple FROM tables. (It's easier to see the logic)
I would change your first query to this:
SELECT r.*, c.country /* any other fields in country besides title */
FROM recipes as r
LEFT JOIN recipeToCountry as rtc ON rtc.recipeId = r.id
LEFT JOIN content.countries as c ON c.id = rtc.countryId
WHERE c.origId = '$country'
You can leave the word "as" out to make it look a little cleaner, but I leave it in there to show what's happening a little better.

how to count duplicate values with joining mysql

$query="SELECT distinct city_name,donnor.donor_id FROM city join bloodgroup ON city.city_id = bloodgroup.city_id join donnor ON bloodgroup.blood_id = donnor.blood_id";?
i want to count how many time city apear in integer..
Have a look at group by and aggregation (count) within select.
It might look something like:
(edited)
select count(city_id)
from city
group by city_id.
That's of cause a minimalistic example without the joins. Also you don't need distinct when you try to count.

SQL query for Selecting from Multiple Tables in single database

I am having 3 tables (c19 , c19b2, g26) in a database
I want to write a SQL Query to search and display all fields of the matched record.
I am using following query:
$query = "SELECT * FROM c19,c19b2,g26 WHERE armyno LIKE '%$searchTerm%'";
But it only works for table c19,
Data from the other 2 tables is not fetched.Each table has a field armyno
Please help me with this
Thank you.
Alright, you are not looking for a JOIN, but a UNION.
SELECT * FROM c19 WHERE armyno LIKE '%$searchTerm%'
UNION
SELECT * FROM c19b2 WHERE armyno LIKE '%$searchTerm%'
UNION
SELECT * FROM g26 WHERE armyno LIKE '%$searchTerm%'
That will let you query all three tables at the same time.
Which DB are you using? This would have worked in SQL Server. However, notice you are doing a cross join of every record to every record... usually you only want to match some records by restriction of a matching key, for example:
select
*
from a
left join b on b.somekey = a.somekey
left join c on c.someotherkey = b.someotherkey
In SQL server you can just say *, but I'm taking it that in your DB engine that didn't work, so try specifying which table. This may in some environments require aliasing as well:
select
a.*,
b.*,
c.*
from tableA as a
left join tableB as b on b.somekey = a.somekey
left join tableC as c on c.someotherkey = b.someotherkey
Generally, you should see the columns from the first table, followed by the columns from the second table, followed by columns from the third table for a given row. If you wanted to get all columns from all tables, but separately, then that would be 3 separate selects.
Lastly, if all 3 tables have "armyno" then I'd expect it to throw an ambiguous field error. In such case you'd want to specify which table's "armyno" field to filter on.

mysql select and join on multiple tables

I'm having tables like
product table: product_id | code
group table: id | fk-product_id | id_code
grade table id | fk-product_id | id_grade
person table id | fk-product_id | id_person
my sql query is:
"SELECT *
FROM product
JOIN group ON group.product_id = product_id
JOIN grade ON grade.product_id = product_id
JOIN person ON person.product_id = product_id
WHERE product.code='".$productCode."'");
I get the wright result, but there is too much of rows. I thing that I'm doing overkill.
All product are for sure in the table "product" but it's not necessary that the same "id_product" is in the table "group", "grade" or "person".
In my result are a lot of rows where my result is repeted. I there any way to avoid those duplication?
Is there better way to perform my query?
From your original query, you have listed the column in the group, grade and person table are
'fk-product_id' but your query is showing as just 'product_id'. So, I am implying your real column is just 'product_id' and the 'fk-' was just a reference that it was the foreign key to products table.
Now, that said, the equality comparison is just product_id. Since you are not qualifying it with alias.field, it is probably grabbing everything since each record in group will always have its own product_id = its own product_id.
In addition, you mention that not all tables will have a matching product ID, so you will need LEFT-JOINs for the other tables... Adjust to something like this
SELECT
p.*,
gp.id_code,
gd.id_grade,
per.id_person
FROM
product p
LEFT JOIN group gp
ON p.product_id = gp.product_id
LEFT JOIN grade gd
ON p.product_id = gd.product_id
LEFT JOIN person per
ON p.product_id = per.product_id
WHERE
p.code='".$productCode."'";
But I would head caution for sql-injection as you could get malicious values in your $productCode variable. Make sure you have it properly cleaned and escaped.
#5er, Left-Join says for each record on the left-side (first in this case is the Product Table), I want all records... and oh... by the way... I have the other tables (group, grade and persons). They MAY have a record too that has the same Product_ID value as the product table. If so, grab those pieces too, but don't exclude the original product record.
Now, why your query was failing, and I thought I described it well, but apparently not. You were getting a Cartesian result which means for every one record in the left-table (product), you were getting EVERY record in the RIGHT-side table... So, for a single product, and if you had 20 group, 10 grades and 100 people, you were basically getting 20,000 records.
So your JOIN
JOIN group ON group.product_id = product_id
WOULD have worked, but had less records IF you qualified with the PRODUCT reference
JOIN group ON group.product_id = PRODUCT.product_id
Otherwise, it was just comparing its own product_ID to itself and saying... Yup, these to product IDs match (even though it was the same record), it returned it. The engine can't guess for you which table you meant for the second part of the join, especially when there were a total of 4 tables referenced in the query, and EACH had a "Product_ID" column. So, I strongly suggest that for ALL your queries, qualify ALL fields as alias.field, including those of the select field list. Then, anyone else trying to help you in the future, or even take over where you left-off know where the fields are. Prevent ambiguity in your queries.
Your select does not match the table/column names above it. For example in table product you say you have column id_product, but in select you use product.id instead of product.id_product. That might be totally different column.
Your results are repeating because the JOIN is joining tables, but you are not filtering those cases where one JOIN matches, while the other isn't.
Try this:
SELECT *
FROM product
JOIN group ON group.product_id = product.id
JOIN grade ON grade.product_id = product.id
JOIN person ON person.product_id = product.id
WHERE product.code='".$productCode."'
GROUP BY product.id

Sorting count in multiple tables

I'm working on a PHP/mySQL table that shows data I've put into my database, and I'm trying to make it sortable. I have two tables in my database:
Table "restaurant" has columns: ID and name
Table "item" has columns: ID, name and restaurantID (restaurantID is set to use the IDs from the "restaurant" table)
What I want to do is sort the restaurants by the number of times their ID shows up in the item table. I'm sure there must be a simple way to do this, Just haven't been able to figure it out. Any help would be greatly appreciated!
Try this...
select r.name, count(i.ID)
from restaurant r
left join item i on i.restaurantID = r.ID
group by r.name
order by count(i.ID) desc
I believe you can do it by using a query like following;
SELECT restaurant.*, COUNT(items.id) AS item_id FROM restaurants, items WHERE restaurant.id = items.restaurant_id ORDER BY item_id ASC;
As you may know, sorting by multiple column is possible as well;
SELECT restaurant.*, COUNT(items.id) AS item_id FROM restaurants, items WHERE restaurant.id = items.restaurant_id ORDER BY item_id ASC, restaurant.`name` DESC;

Categories