How to merge two MySQL queries together - php

How can I merge the following queries together?
To get all the objects of a particular type I use
SELECT ID FROM social_objects
WHERE subgroup='23' ORDER BY time_created DESC LIMIT 0 , 30
I have this search too, for titles
SELECT ID FROM 'social_objects_single'
WHERE 'title' LIKE '%indian%' LIMIT 0 , 30
How can I get only objects of subgroup 23 with certain titles?

How are the two tables related? If they both reference an ID you inner join and use AND to combine conditions:
SELECT Parent.ID, Child.ID
FROM ParentTable
INNER JOIN ChildTable ON ParentTable.ID = ChildTable.ForeignKeyID
WHERE Parent.ID = 23 AND Title LIKE '%indian%'

If your social_objects_single has the same ID as the social_objects table you could do this:
SELECT so.ID FROM social_objects so
INNER JOIN social_objects_single soi ON soi.ID = so.ID
WHERE so.subgroup = 23 AND soi.title LIKE '%indian%'
ORDER BY so.time_created DESC LIMIT 0, 30;

SELECT SO.ID,SOS.ID
FROM social_objects SO ,social_objects_single SOS WHERE SOS.title LIKE '%indian% and SO.subgroup=23 and SOS.id =SO.subgroup_id
you should replace the last condition SOS.id =SO.subgroup_id as your tables are connected

Related

Get data from two tables

I have a query regarding join . Basically there are two tables product and product_boost . The table product_boost has the product_id as foreign key which is also in product table .
I want to get the data using join which is available in both the tables, and if not only data from first table will come.
I am using right outer join, here is my query
SELECT * FROM `vefinder_product`
RIGHT OUTER JOIN `vefinder_product_boost` ON `vefinder_product_boost`.`product_id`=`vefinder_product`.`product_id`
WHERE `vefinder_product`.`status` = 1
AND `vefinder_product`.`post_type` != 5
AND `vefinder_product`.`country` IN('348')
AND `vefinder_product`.`product_stock` >0
AND `vefinder_product`.`product_in_stock` = 1
AND `vefinder_product_boost`.`target_age_from` >= 20
AND `vefinder_product_boost`.`target_age_to` <= 40
ORDER BY `vefinder_product`.`is_boosted` DESC,
`vefinder_product`.`is_sponsered` DESC,
`vefinder_product`.`created_date` DESC LIMIT 21
How can i achive the desired thing , because this is not working. I am using codeigniter php.
Use Left join instead, if you want to get all the data from first (leftmost) table.
Any Where conditions on tables other than the first table (leftmost), should be shifted to ON condition in Left Join. Otherwise, Where would filter out unmatched rows also (null in the right side tables).
Try the following instead:
SELECT *
FROM `vefinder_product`
LEFT OUTER JOIN `vefinder_product_boost`
ON `vefinder_product_boost`.`product_id`=`vefinder_product`.`product_id` AND
`vefinder_product_boost`.`target_age_from` >= 20 AND
`vefinder_product_boost`.`target_age_to` <= 40
WHERE `vefinder_product`.`status` = 1 AND
`vefinder_product`.`post_type` != 5 AND
`vefinder_product`.`country` IN('348') AND
`vefinder_product`.`product_stock` >0 AND
`vefinder_product`.`product_in_stock` = 1
ORDER BY `vefinder_product`.`is_boosted` DESC,
`vefinder_product`.`is_sponsered` DESC,
`vefinder_product`.`created_date` DESC
LIMIT 21
Use left join and put where condition in ON cluase
SELECT * FROM `vefinder_product`
left OUTER JOIN `vefinder_product_boost` ON `vefinder_product_boost`.`product_id`=`vefinder_product`.`product_id`
and `vefinder_product`.`status` = 1
AND `vefinder_product`.`post_type` != 5
AND `vefinder_product`.`country` IN('348')
AND `vefinder_product`.`product_stock` >0
AND `vefinder_product`.`product_in_stock` = 1
AND `vefinder_product_boost`.`target_age_from` >= 20
AND `vefinder_product_boost`.`target_age_to` <= 40
ORDER BY `vefinder_product`.`is_boosted` DESC,
`vefinder_product`.`is_sponsered` DESC,
`vefinder_product`.`created_date` DESC LIMIT 21
you can use third party software like SQLyog.
it is very simple for join query just build query with UI and assign relation to that fields between tables.
in sqlyog you can get data from multiple tables not only two tables.
because i am currently using this software for time saving.

Query to fetch multiple data by joining multiple tables using PHP and MySQL

I need one help .I need to fetch some data after joining the multiple table using PHP and Mysql so i need the appropriate query for that.I am explaining my table structure below.
db_order:
id order_id promocode
1 10 A12016
2 11 A12016
db_order_product:
id order_id pro_data_id quantity
1 10 20 2
2 10 22 3
3 11 20 1
db_product_info:
pro_data_id product_name
20 abc
22 xyz
I have tried something like below but its not working.
$sqlqry="select * from db_order order by id desc";
$orderqry=mysqli_query($con,$sqlqry);
while($row=mysqli_fetch_assoc($orderqry)){
$order_id=$row['order_id'];
$sqlproqry="select * from db_order_products where order_id='".$order_id."'";
$proqry=mysqli_query($con,$sqlproqry);
while($row1=mysqli_fetch_assoc($proqry)){
$product_data_id=$row1['pro_data_id'];
$sqldataqry="select * from db_product_data where pro_data_id='".$product_data_id."'";
$prodataqry=mysqli_query($con,$sqldataqry);
while($prodatarow=mysqli_fetch_assoc($prodataqry)){
$pro_id=$prodatarow['pro_Id'];
$sqlpro="select * from db_product_info where pro_Id='".$pro_id."'";
$prodata=mysqli_query($con,$sqlpro);
$prorow=mysqli_fetch_array($prodata);
}
}
$result[]=array('id'=>$row['id'],'order_id'=>$row['order_id'],'promocode'=>$row['promocode'],'order_pro_id'=>$row1['id'],'pro_data_id'=>$row1['pro_data_id'],'pro_quantity'=>$row1['quantity'],'product_name'=>$prorow['Product_name']);
}
echo json_encode($result);
Here i need first user will go to db_order table fetch all value and according to the order_id the all data should fetch from db_order_product then as per pro_data_id from db_order_product table it will fetch data from db_product_info table and finaly return all data in an array.Please help me.
Just use a simple JOIN
SELECT o.id, o.order_id, o.promocode, p.id AS order_pro_id, p.prod_data_id, p.quantity AS pro_quantity, i.product_name
FROM db_order AS o
JOIN db_order_products AS p ON o.order_id = p.order_id
JOIN db_product_data AS d ON p.pro_data_id = d.pro_data_id
JOIN db_product_info AS i ON i.pro_Id = d.pro_Id
ORDER BY o.id DESC
you must fix you query:
use this query instead:
select * from db_order,db_order_product,db_product_info where db_order.order_id=db_order_product.order_id and db_order_product.pro_data_id=db_product_info.pro_data_id
SELECT dor.id,dordor.order_id,dor.promocode
FROM db_order AS dor
JOIN db_order_product AS dop ON dop.order_id = dor.order_id
JOIN db_product_info as dpi ON dpi.pro_data_id=dop.pro_data_id

MySQL #1241 - Operand should contain 1 column(s) on counting

I am running this query, and I am getting ** #1241 - Operand should contain 1 column(s)** error:
SELECT `forumCategories`.`id`, `forumCategories`.`name`, `forumCategories`.`order`, `forumCategories`.`description`, `forumCategories`.`date_created`, COUNT(forumPosts.forumCategory_id) as postCount,
(SELECT `forumPosts`.*, `forumChildPosts`.`id`, `forumChildPosts`.`forumPost_id`, COUNT(forumChildPosts.forumPost_id) as childCount FROM `forumChildPosts` LEFT JOIN `forumPosts` ON `forumPosts`.`id` = `forumChildPosts`.`forumPost_id` GROUP BY `forumPosts`.`id`) AS childCount
FROM `forumCategories`
LEFT JOIN `forumPosts` ON `forumCategories`.`id` = `forumPosts`.`forumCategory_id`
GROUP BY `forumCategories`.`id`
ORDER BY `forumCategories`.`order` DESC
I have 3 tables:
forumCategories
forumPosts | forumPosts.forumCategory_id = forumCategories.id
forumChildPosts | forumChildPosts.forumPosts_id = forumPosts.id
I want to count all posts for the forum category, and them I want to count all the child posts that belongs to that forum category. How can I do this?
You can't select several items with a subselect and then give them one name. Now you're getting everything from forumPosts, something from forumChildPosts etc and trying to put that into a single column, childCount. This is not allowed.
It might be enough to remove all other result columns from that select and only leave the count?
I couldn't try it, is that makes sense ? But you can't get nested results from mysql due to its limitation, MYSQL is a Matrix table.
SELECT `forumCategories`.`id`,
`forumCategories`.`name`,
`forumCategories`.`order`,
`forumCategories`.`description`,
`forumCategories`.`date_created`,
COUNT(forumPosts.forumCategory_id) AS postCount,
(SELECT COUNT(forumChildPosts.forumPost_id) AS childCount FROM `forumChildPosts` LEFT JOIN `forumPosts` ON `forumPosts`.`id` = `forumChildPosts`.`forumPost_id` GROUP BY `forumPosts`.`id`) AS childCount
FROM `forumCategories`
LEFT JOIN `forumPosts` ON `forumCategories`.`id` = `forumPosts`.`forumCategory_id`
GROUP BY `forumCategories`.`id`
ORDER BY `forumCategories`.`order` DESC

How to find required unique result

I have two table 'topic' and 'subcategory'
I am using this query--
Select * from `subcategory` as s
Inner join `topic` as f
WHERE s.`Subcategory_id` = f.`Subcategory_id
My result shows like
Category_id Subcategory_id Post_id time
2 2.3 4 2012-12-01
1 1.5 5 2013-01-20
1 1.3 6 2013-03-18
There's also other columns... but all I want is to select the latest Post_id and Subcategory_id of one Category_id ... that means here Category 1 has two Subcategory it will select only the latest(here 1.3) and same result all the time for all Category when database will grown larger. What will be the next query or how could I change the existing query to gain my desired result?
SELECT Post_Id, Subcategory_Id from subcategory as s, topic as t where
s.Subcategory_id = t.Subcategory_id and time = (
SELECT Max(time) from subcategory as s1, topic as t1 where
s1.Subcategory_id = t1.Subcategory_id and s1.Category_id = s.Category_id
);
Something like that, I think, will work.
SELECT TOP 1 ... ORDER BY whatever column determines "the latest"
e.g.
SELECT TOP 1 ... ORDER BY TIME DESCENDING
Or in case of mysql:
SELECT ... ORDER BY TIME DESCENDING LIMIT 1
Join your topic table with following query:
SELECT s.* FROM subcategory s
Inner JOIN (SELECT s1.Category_id,
MAX(s1.time1) AS max_time
FROM subcategory s1
GROUP BY s1.Category_id) y
ON y.Category_id = s.Category_id AND y.max_time = s.time1

Need help in optimising query

I have two tables - incoming tours(id,name) and incoming_tours_cities(id_parrent, id_city)
id in first table is unique, and for each unique row from first table there is the list of id_city - s in second table(i.e. id_parrent in second table is equal to id from first table)
For example
incoming_tours
|--id--|------name-----|
|---1--|---first_tour--|
|---2--|--second_tour--|
|---3--|--thirth_tour--|
|---4--|--hourth_tour--|
incoming_tours_cities
|-id_parrent-|-id_city-|
|------1-----|---4-----|
|------1-----|---5-----|
|------1-----|---27----|
|------1-----|---74----|
|------2-----|---1-----|
|------2-----|---5-----|
........................
That means that first_tour has list of cities - ("4","5","27","74")
AND second_tour has list of cities - ("1","5")
Let's assume i have two values - 4 and 74:
Now, i need to get all rows from first table, where my both values are in the list of cities. i.e it must return only the first_tour (because 4 and 74 are in it's list of cities)
So, i wrote the following query
SELECT t.name
FROM `incoming_tours` t
JOIN `incoming_tours_cities` tc0 ON tc0.id_parrent = t.id
AND tc0.id_city = '4'
JOIN `incoming_tours_cities` tc1 ON tc1.id_parrent = t.id
AND tc1.id_city = '74'
And that works fine.
But i generate the query dynamically, and when the count of joins is big (about 15) the query slowing down.
i.e. when i try to run
SELECT t.name
FROM `incoming_tours` t
JOIN `incoming_tours_cities` tc0 ON tc0.id_parrent = t.id
AND tc0.id_city = '4'
JOIN `incoming_tours_cities` tc1 ON tc1.id_parrent = t.id
AND tc1.id_city = '74'
.........................................................
JOIN `incoming_tours_cities` tc15 ON tc15.id_parrent = t.id
AND tc15.id_city = 'some_value'
the query run's in 45s(despite on i set indexes in the tables)
What can i do, to optimaze it?
Thanks much
SELECT t.name
FROM incoming_tours t INNER JOIN
( SELECT id_parrent
FROM incoming_tours_cities
WHERE id IN (4, 74)
GROUP BY id_parrent
HAVING count(id_city) = 2) resultset
ON resultset.id_parrent = t.id
But you need to change number of total cities count.
SELECT name
FROM (
SELECT DISTINCT(incoming_tours.name) AS name,
COUNT(incoming_tours_cities.id_city) AS c
FROM incoming_tours
JOIN incoming_tours_cities
ON incoming_tours.id=incoming_tours_cities.id_parrent
WHERE incoming_tours_cities.id_city IN(4,74)
HAVING c=2
) t1;
You will have to change c=2 to whatever the count of id_city you are searching is, but since you generate the query dynamically, that shouldn't be a problem.
I'm pretty sure this works, but a lot less sure that it is optimal.
SELECT * FROM incoming_tours
WHERE
id IN (SELECT id_parrent FROM incoming_tours_cities WHERE id_city=4)
AND id IN (SELECT id_parrent FROM incoming_tours_cities WHERE id_city=74)
...
AND id IN (SELECT id_parrent FROM incoming_tours_cities WHERE id_city=some_value)
Just an hint.
If you use the IN operator in a WHERE clause, you can hope that the short-circuit of operator AND may remove unnecessary JOINs during the execution for the tours that do not respect the constraint.
Seems like an odd way to do that query, here
SELECT t.name FROM `incoming_tours` as t WHERE t.id IN (SELECT id_parrent FROM `incoming_tours_cities` as tc WHERE tc.id_city IN ('4','74'));
I think that does it, but not tested...
EDIT: Added table alias to sub-query
I've written this query using CTE's and it includes the test data in the query. You'll need to modify it so that it queries the real tables instead. Not sure how it performs on a large dataset...
Declare #numCities int = 2
;with incoming_tours(id, name) AS
(
select 1, 'first_tour' union all
select 2, 'second_tour' union all
select 3, 'third_tour' union all
select 4, 'fourth_tour'
)
, incoming_tours_cities(id_parent, id_city) AS
(
select 1, 4 union all
select 1, 5 union all
select 1, 27 union all
select 1, 74 union all
select 2, 1 union all
select 2, 5
)
, cityIds(id_city) AS
(
select 4
union all select 5
/* Add all city ids you need to check in this table */
)
, common_cities(id_city, tour_id, tour_name) AS
(
select c.id_city, it.id, it.name
from cityIds C, Incoming_tours_cities tc, incoming_tours it
where C.id_city = tc.id_city
and tc.id_parent = it.id
)
, tours_with_all_cities(id_city) As
(
select tour_id from common_cities
group by tour_id
having COUNT(id_city) = #numCities
)
select it.name from incoming_tours it, tours_with_all_cities tic
where it.id = tic.id_city

Categories