I know this can be confusing, but please bear with me on this one.
I have two SELECT queries with a minor difference which returns pretty much the same result set.
SELECT products_id,options_values_id
FROM products_attributes pa
LEFT JOIN products_options po ON ( pa.options_id = po.products_options_id )
WHERE products_id ='574' and pa.options_id!=6
and pa.options_id!=3
AND products_options_type = 6
GROUP BY products_id,options_values_id
ORDER BY products_id,products_options_sort_order,options_id
The second query varies at products_options_type
SELECT products_id,options_values_id
FROM products_attributes pa
LEFT JOIN products_options po ON ( pa.options_id = po.products_options_id )
WHERE products_id ='574' and pa.options_id!=6
and pa.options_id!=3
AND products_options_type = 2
GROUP BY products_id,options_values_id
ORDER BY products_id,products_options_sort_order,options_id
And the results returned by them are
574|193
574|204
AND
574|25
574|3
I want the output as
574|193|25
574|204|3
What I tried is:
SELECT pa.products_id,pa.options_values_id,ord.options_values_id
FROM products_attributes pa
LEFT JOIN products_options po ON ( pa.options_id = po.products_options_id )
LEFT JOIN(SELECT products_id,options_values_id
FROM products_attributes pa
LEFT JOIN products_options po ON ( pa.options_id = po.products_options_id )
WHERE products_id ='574' and pa.options_id!=6
and pa.options_id!=3
AND products_options_type = 2
GROUP BY products_id,options_values_id
ORDER BY products_id,products_options_sort_order,options_id)ord ON pa.products_id=ord.products_id
WHERE paproducts_id ='574' and pa.options_id!=6
and pa.options_id!=3
AND products_options_type = 2
GROUP BY pa.products_id,pa.options_values_id
ORDER BY pa.products_id,products_options_sort_order,options_id
However this returns
574|193|25
574|204|25
I am not too good with joins, so any idea if and how this can be done?
Try this
SELECT a.products_id,a.options_values_id, b.options_values_id
FROM (SELECT #rownum:=#rownum+1 'rw', products_id, options_values_id
FROM (SELECT #rownum:=0) r, products_attributes pa
LEFT JOIN products_options po ON ( pa.options_id = po.products_options_id )
WHERE products_id ='574' and pa.options_id!=6
and pa.options_id!=3
AND products_options_type = 6
GROUP BY products_id,options_values_id
ORDER BY products_id,products_options_sort_order,options_id) a,
(SELECT #rownum:=#rownum+1 'rw', products_id,options_values_id
FROM (SELECT #rownum:=0) r, products_attributes pa
LEFT JOIN products_options po ON ( pa.options_id = po.products_options_id )
WHERE products_id ='574' and pa.options_id!=6
and pa.options_id!=3
AND products_options_type = 2
GROUP BY products_id,options_values_id
ORDER BY products_id,products_options_sort_order,options_id) b
WHERE a.products_id=b.products_id and a.rw=b.rw;
Hope this helps.
Try below query, here i took join on product_options twice, 1 for po.products_options_type = 6 and 2nd for po1.products_options_type = 2
SELECT pa.products_id,po.options_values_id,po1.options_values_id
FROM products_attributes pa
LEFT JOIN products_options po ON ( pa.options_id = po.products_options_id and po.products_options_type = 6)
LEFT JOIN products_options po1 ON ( pa.options_id = po1.products_options_id and po.products_options_type = 2)
WHERE pa.products_id ='574' and pa.options_id!=6
and pa.options_id!=3
GROUP BY products_id,po1.options_values_id,po1.options_values_id
ORDER BY products_id,products_options_sort_order,options_id
Alternative solution:
select v1,v2,v3, v4 from (SELECT products_id v1,options_values_id v2
FROM products_attributes pa
LEFT JOIN products_options po ON ( pa.options_id = po.products_options_id )
WHERE products_id ='574' and pa.options_id!=6
and pa.options_id!=3
AND products_options_type = 6
GROUP BY products_id,options_values_id
ORDER BY products_id,products_options_sort_order,options_id) t1,
(SELECT products_id v3,options_values_i v4
FROM products_attributes pa
LEFT JOIN products_options po ON ( pa.options_id = po.products_options_id )
WHERE products_id ='574' and pa.options_id!=6
and pa.options_id!=3
AND products_options_type = 2
GROUP BY products_id,options_values_id
ORDER BY products_id,products_options_sort_order,options_id) t2
where t1.products_id=t2.products_id
You can sort it easily.
Related
I just want my query to return a result looking like this:
array(
[k1] => data1
[k2] => data2
[items] => array(
[item1] => array(
.... data inside
)
[item2] => array(
.... data inside
)
)
)
Here is my query:
SELECT o.*
, ot.tracking_number
, p.id payId
, p.customer_id payCustId
, p.name payName
, p.status payStatus
, p.charge payTotalCharge
, op.*
FROM orders o
JOIN payments o
ON p.id = o.payment_id
LEFT
JOIN orders_tracking ot
ON ot.order_id = o.id
JOIN orderdetails od
ON od.order_id = o.id
JOIN orderproducts op
ON op.orderdetail_id = od.id
WHERE p.customer_id = $customer_id;
What is wrong with my query that it won't return the way I wanted it to?
Thanks.
I've a requirement to show the similar products in product detail page in such a way that the products listed should match the current product properties in a hierarchical way as given below
Size, color, category, company should match with the current product
Size, color, category should match with the current product
Size, color should match with the current product
Size should match with the current product
My sql query is as given below:
(SELECT pd.product_id, pd.name, p.price
FROM mg_product_description pd
JOIN `mg_product` p ON p.product_id = pd.product_id
WHERE
pd.size_id = '33' AND
pd.color_id = '2' AND
pd.category_id = '3' AND
pd.company_id = '1' AND
pd.product_id != '53' AND
p.status = '1'
ORDER BY RAND() LIMIT 10
)
UNION
(SELECT pd.product_id, pd.name, p.price
FROM mg_product_description pd
JOIN `mg_product` p ON p.product_id = pd.product_id
WHERE
pd.size_id = '33' AND
pd.color_id = '2' AND
pd.category_id = '3' AND
pd.product_id != '53' AND
p.status = '1'
ORDER BY RAND() LIMIT 10
)
UNION
(SELECT pd.product_id, pd.name, p.price
FROM mg_product_description pd
JOIN `mg_product` p ON p.product_id = pd.product_id
WHERE
pd.size_id = '33' AND
pd.color_id = '2' AND
pd.product_id != '53' AND
p.status = '1'
ORDER BY RAND() LIMIT 10
)
UNION
(SELECT pd.product_id, pd.name, p.price
FROM mg_product_description pd
JOIN `mg_product` p ON p.product_id = pd.product_id
WHERE
pd.size_id = '33' AND
pd.product_id != '53' AND
p.status = '1'
ORDER BY RAND() LIMIT 10
)
53 - current product id and status denotes available!
Is there any way to optimize the above query?
Note Output required: We need 10 similar products. If there exists 4 products matching condition 1, then they need to listed at first in random order. Similarly we need to list the products matching other conditions below it.
Thanks in Advance!
Keeping using ORDER BY RAND() (which is not efficient) then a very basic improvement would be to add a priority for each clause, move the order clause to the end so it is only needed once.
(SELECT pd.product_id, pd.name, p.price , 1 AS recpriority
FROM mg_product_description pd
JOIN `mg_product` p ON p.product_id = pd.product_id
WHERE
pd.size_id = '33' AND
pd.color_id = '2' AND
pd.category_id = '3' AND
pd.company_id = '1' AND
pd.product_id != '53' AND
p.status = '1'
)
UNION
(SELECT pd.product_id, pd.name, p.price , 2 AS recpriority
FROM mg_product_description pd
JOIN `mg_product` p ON p.product_id = pd.product_id
WHERE
pd.size_id = '33' AND
pd.color_id = '2' AND
pd.category_id = '3' AND
pd.product_id != '53' AND
p.status = '1'
)
UNION
(SELECT pd.product_id, pd.name, p.price , 3 AS recpriority
FROM mg_product_description pd
JOIN `mg_product` p ON p.product_id = pd.product_id
WHERE
pd.size_id = '33' AND
pd.color_id = '2' AND
pd.product_id != '53' AND
p.status = '1'
)
UNION
(SELECT pd.product_id, pd.name, p.price , 4 AS recpriority
FROM mg_product_description pd
JOIN `mg_product` p ON p.product_id = pd.product_id
WHERE
pd.size_id = '33' AND
pd.product_id != '53' AND
p.status = '1'
)
ORDER BY recpriority, RAND() LIMIT 10
That could then be done without the need for unions by doing something like this:-
SELECT pd.product_id,
pd.name,
p.price ,
CASE
WHEN pd.color_id = '2' AND pd.category_id = '3' AND pd.company_id = '1' THEN 1
WHEN pd.color_id = '2' AND pd.category_id = '3' THEN 2
WHEN pd.color_id = '2' THEN 3
ELSE 4
END AS recpriority
FROM mg_product_description pd
JOIN `mg_product` p ON p.product_id = pd.product_id
WHERE pd.size_id = '33'
AND pd.product_id != '53'
AND p.status = '1'
ORDER BY recpriority, RAND()
LIMIT 10
I have this sql that is made by help of others.
$sql ="
select e.*, i.*, group_concat( t.tag separator ',') as tag_list
from nv_entries e
JOIN nv_tags t on t.entrie_id = e.id
LEFT JOIN nv_images i on i.entrie_id = e.id
where t.tag in ( $tag_list )
group by e.id
having count(t.id) = $num_tags ";
The result is this (i only show one entrie here, could be more):
[1] => Array
(
[id] => 2
[band] => Kids for Cash
[album] => No More Walls E.P.
[label] =>
[year] => 1986
[text] => Text about album kids for cash.
[entrie_id] => 2
[source] => img02_9lch1.png
[tag_list] => tree
)
For the tags, i have to show all tags that a entrie has and highlight the tags that where used to get the result. In this case [tag_list] => tree only shows one tag, the one that was used in the search field. My question is, how can i get a result like this?:
...
[tag_list] => tree, green, foo, bar
[used_tags] => tree
)
As a array is also good, but then please also an array when it's just one item.
If I understood correctly use >= in the having condition
$sql ="
select e.*, i.*, group_concat( t.tag separator ',') as tag_list
from nv_entries e
LEFT JOIN nv_images i on i.entrie_id = e.id
JOIN nv_tags t on t.entrie_id = e.id
where t.tag in ( $tag_list )
group by e.id
having count(t.id) >= $num_tags ";
ADD
subquery approach:
$sql ="
select e.*, i.*, group_concat( t.tag separator ',') as tag_list
from nv_entries e
JOIN nv_tags t on t.entrie_id in (
select se.id
from nv_entries se
JOIN nv_tags st on st.entrie_id = se.id
where st.tag in ( $tag_list )
group by se.id
having count(st.id) >= $num_tags
)
LEFT JOIN nv_images i on i.entrie_id = e.id
WHERE 1
group by e.id
";
Into subquery I get the ID list of entrie havin at least requested tags, then in main query I get all infox
ADD fixed query (see asker comment)
subquery approach, fix the lost join between "e" and "t" :
$sql ="
select e.*, i.*, group_concat( t.tag separator ',') as tag_list
from nv_entries e
JOIN nv_tags t on t.entrie_id = e.id
LEFT JOIN nv_images i on i.entrie_id = e.id
WHERE e.id in (
select se.id
from nv_entries se
JOIN nv_tags st on st.entrie_id = se.id
where st.tag in ( $tag_list )
group by se.id
having count(st.id) >= $num_tags
)
group by e.id
";
I have this query string...
select i.invoiceid, i.date, i.total, i.total - (select ifnull(sum(p.amount), 0) from payment p where p.invoice = i.invoiceid) as remainingbalance
from invoice i inner join client c
on i.client = c.clientid
where i.isdeleted = 0 and i.client = 1
union
select p.paymentid, p.date, p.invoice, p.amount from payment p inner join invoice i
on i.invoiceid = p.invoice
inner join paymenttype
on paymenttype.paymenttypeid = p.paymenttypeid
inner join client c
on c.clientid = i.client
where c.clientid = 1
and i.isdeleted = 0
order by date
when I try this...
<?php
echo $clientArrayInvoice[1]['paymentid'];
?>
I get no results when I do a print_r on on $clientArrayInvoice I get this
Array ( [0] => Array ( [invoiceid] => 1 [date] => 2012-04-12 [total] => 602.29 [remainingbalance] => 300.96 ) [1] => Array ( [invoiceid] => 1 [date] => 2012-04-27 [total] => 1.00 [remainingbalance] => 301.33 ) )
I understand why its doing this, but how do I get the column to say paymentid instead of invoiceid for the results returned. so I can determine what is a paymentid and what is a invoiceid I hope this makes sense.
select i.invoiceid as transactionid, i.date, i.total,
i.total - (select ifnull(sum(p.amount), 0) from payment p where p.invoice = i.invoiceid) as remainingbalance,
'invoice' as transaction_type
from invoice i inner join client c
on i.client = c.clientid
where i.isdeleted = 0 and i.client = 1
union
select p.paymentid as transactionid, p.date, p.invoice, p.amount, 'payment' as transaction_type
from payment p inner join invoice i
on i.invoiceid = p.invoice
inner join paymenttype
on paymenttype.paymenttypeid = p.paymenttypeid
inner join client c
on c.clientid = i.client
where c.clientid = 1
and i.isdeleted = 0
order by date
My users have pages:
user favorites
users image
I try to do a page "everything" which will get data from 2 sql tables (already have sql code) to one html page ordering all by date. Problem is that "user image" have one html structure and "user favorites" another. Many website have such pages where is output different data in different html structure from different tables. Today I first time tried to do this and do not know the correct way.
My tables:
users
id
username
images
id
user_id
image
description
date <--- uplaod date
user_favorites
id
user_id <---user id who like image
image_id <---id of liked image
date <---date when image was clicked "liked"
I get user images with this sql
function users_pictures($user_id)
{
$sql = "SELECT username as user, p.image as user_image, i.image, i.id as image_id, i.description as text, UNIX_TIMESTAMP(i.date) as image_date, COALESCE ( imgcount.cnt, 0 ) as comments
FROM users u
LEFT JOIN images i ON i.user_id = u.id
LEFT JOIN images p ON p.id = (SELECT b.id FROM images AS b where u.id = b.user_id ORDER BY b.id DESC LIMIT 1)
LEFT JOIN (SELECT image_id, COUNT(*) as cnt FROM commentaries GROUP BY image_id ) imgcount ON i.id = imgcount.image_id
WHERE i.user_id = ?
ORDER BY i.date DESC";
$query = $this->db->query($sql, $user_id);
return $query->result_array();
}
I get all users image and user current image - avatar (last upload image is user avatar)
return example :
[images_list] => Array
(
[0] => Array
(
[user] => 8888
[user_image] => http://127.0.0.1/auth_system_1/upload_images/24/24_0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
[image] => http://127.0.0.1/auth_system_1/upload_images/224/224_0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
[image_id] => 4
[text] =>
[image_date] => 50 minutes
[comments] => 0
[user_first_image] => 1
)
)
User favorite table is :
function users_favorites_list($user_id)
{
$sql = "SELECT
u.username as user,
p.image as user_image,
fav.id as favorite_id,
UNIX_TIMESTAMP(fav.date) as favorite_date,
i.id as images_id,
i.image,
i.description as text,
u2.username as favorite_user,
t.image as favorite_user_image
FROM users u
LEFT JOIN user_favorites fav ON fav.user_id = u.id
LEFT JOIN user_follow f ON f.follow_id = fav.user_id
LEFT JOIN images i ON i.id = fav.image_id
LEFT JOIN users u2 ON u2.id = i.user_id
LEFT JOIN images p ON p.id = (SELECT b.id FROM images AS b where fav.user_id = b.user_id ORDER BY b.id DESC LIMIT 1)
LEFT JOIN images t ON t.id = (SELECT b.id FROM images AS b where u2.id = b.user_id ORDER BY b.id DESC LIMIT 1)
WHERE fav.user_id = ?
GROUP BY fav.id
ORDER BY fav.date DESC";
$query = $this->db->query($sql, array($user_id, $user_id));
return $query->result_array();
}
return example:
Array
(
[0] => Array
(
[user] => 8888
[user_image] => http://127.0.0.1/auth_system_1/upload_images/24/24_0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
[favorite_id] => 5
[favorite_date] => 18 minutes ago
[images_id] => 2
[image] => http://127.0.0.1/auth_system_1/upload_images/100/100_flw3utn9igiqh7dtt2o61ydf8_174.jpeg
[text] => 3
[favorite_user] => 6666
[favorite_user_image] => http://127.0.0.1/auth_system_1/upload_images/24/24_flw3utn9igiqh7dtt2o61ydf8_174.jpeg
)
[1] => Array
(
[user] => 8888
[user_image] => http://127.0.0.1/auth_system_1/upload_images/24/24_0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
[favorite_id] => 2
[favorite_date] => 1 week ago
[images_id] => 4
[image] => http://127.0.0.1/auth_system_1/upload_images/100/100_0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
[text] =>
[favorite_user] => 8888
[favorite_user_image] => http://127.0.0.1/auth_system_1/upload_images/24/24_0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
)
)
:
![My html structure where I try to return data from 2 sql][1]
I need select user activities from 2 table in one page with different html structures (example see image) . I think many peole do it. Please tell me how to do this?
[everything_list] => Array
(
[0] => Array
(
[user] => 8888
[user_image] => 0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
[favorite_id] => 5
[favorite_date] => 1328565406
[images_id] => 2
[image] => flw3utn9igiqh7dtt2o61ydf8_174.jpeg
[text] => 3
[favorite_user] => 6666
[favorite_user_image] => flw3utn9igiqh7dtt2o61ydf8_174.jpeg
)
[1] => Array
(
[user] => 8888
[user_image] => 0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
[favorite_id] => 2
[favorite_date] => 1327856547
[images_id] => 4
[image] => 0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
[text] =>
[favorite_user] => 8888
[favorite_user_image] => 0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
)
)
The query below return what you need?
SELECT
username as user,
p.image as user_image,
i.image,
i.id as image_id,
i.description as text,
UNIX_TIMESTAMP(i.date) as image_date,
COALESCE ( imgcount.cnt, 0 ) as comments,
fav.id as favorite_id,
UNIX_TIMESTAMP(fav.date) as favorite_date,
u2.username as favorite_user,
t.image as favorite_user_image
FROM users u
LEFT JOIN user_favorites fav ON fav.user_id = u.id
LEFT JOIN user_follow f ON f.follow_id = fav.user_id
LEFT JOIN images i ON i.user_id = u.id
LEFT JOIN users u2 ON u2.id = i.user_id
LEFT JOIN images p ON p.id = (SELECT b.id FROM images AS b where u.id = b.user_id ORDER BY b.id DESC LIMIT 1)
LEFT JOIN (SELECT image_id, COUNT(*) as cnt FROM commentaries GROUP BY image_id ) imgcount ON i.id = imgcount.image_id
LEFT JOIN images t ON t.id = (SELECT b.id FROM images AS b where u2.id = b.user_id ORDER BY b.id DESC LIMIT 1)
WHERE u.user_id = ?
GROUP BY fav.id
ORDER BY i.date DESC