union with group by mysql - mysql

Hi I have a query as follows but group by is not working.
SELECT messages.thread_id,messages.subject,messages.message_id,messages.status,messages.attachment,login.name, DATE_FORMAT( messages.date, '%D-%b-%Y' ) as date from messages inner join login on messages.receiver = login.id where (messages.sender = '" . mysql_real_escape_string(trim($_SESSION['login_id'])) . "' and messages.status = 'trash' )
UNION SELECT messages.thread_id,messages.subject,messages.message_id,messages.status,messages.attachment,login.name, DATE_FORMAT( messages.date, '%D-%b-%Y' ) as date from messages inner join login on messages.sender = login.id where (messages.receiver = '" . mysql_real_escape_string(trim($_SESSION['login_id'])) . "' and messages.status = 'trash') GROUP BY messages.thread_id

Wrap your query to an outer query so that it can group the combined results from both the queries.
SELECT z.*
FROM
(
SELECT messages.thread_id, messages.subject, messages.message_id, messages.status,
messages.attachment, login.name, DATE_FORMAT( messages.date, '%D-%b-%Y' ) as date
FROM messages
INNER JOIN login ON messages.receiver = login.id
WHERE messages.sender = '" . mysql_real_escape_string(trim($_SESSION['login_id'])) . "'
AND messages.status = 'trash'
UNION
SELECT messages.thread_id, messages.subject, messages.message_id, messages.status,
messages.attachment, login.name, DATE_FORMAT( messages.date, '%D-%b-%Y' ) as date
FROM messages
INNER JOIN login ON messages.sender = login.id
WHERE messages.receiver = '" . mysql_real_escape_string(trim($_SESSION['login_id'])) . "'
AND messages.status = 'trash'
) AS z
GROUP BY z.thread_id

You have to put brackets around the union select, give it an alias and select from it:
SELECT A.* FROM
(messages.thread_id,messages.subject,messages.message_id,messages.status,mess
ages.attachment,login.name, DATE_FORMAT( messages.date, '%D-%b-%Y' ) as
date from messages inner join login on messages.receiver = login.id
where (messages.sender = '" .
mysql_real_escape_string(trim($_SESSION['login_id'])) . "' and
messages.status = 'trash' )
UNION SELECT
messages.thread_id,messages.subject,messages.message_id,messages.status,messa
ges.attachment,login.name, DATE_FORMAT( messages.date, '%D-%b-%Y' ) as
date from messages inner join login on messages.sender = login.id where
(messages.receiver = '" .
mysql_real_escape_string(trim($_SESSION['login_id'])) . "' and
messages.status = 'trash')) AS A
GROUP BY A.thread_id

Related

How to change a query in mysql so it retrieve 30 rows randomly

I'd like to change this query in my WordPress plugin so that it retrieves 30 random rows out of 100.
$query = $wpdb->prepare("
SELECT
p.*, qq.quiz_id, qq.question_order AS order
FROM
{$wpdb->posts} p
INNER JOIN
{$wpdb->prefix}learnpress_quiz_questions qq ON p.ID = qq.question_id
WHERE
qq.quiz_id IN (" . join( ',', $format ) . ")
AND
p.post_status = %s
", $args );
I've changed it to this but it still does not work. Could any body help me ,please?
SELECT
p.*, qq.quiz_id, qq.question_order AS order
FROM
{$wpdb->posts} p
INNER JOIN
{$wpdb->prefix}learnpress_quiz_questions qq ON p.ID = qq.question_id
WHERE
qq.quiz_id IN (" . join( ',', $format ) . ")
AND
p.post_status = %s
ORDER BY
RAND() LIMIT 30
Change your sort to something like this:
order by RAND() * 30
or if you have an integer id:
order by RAND() * id

include wholesale field in mysql query

I am using Opencart 2.2.0. I have two customer groups - default and wholesale customers. Throughout my web site, price field is for default group, and wholesale field is for wholesale customer group. I also added wholesale field in specials tab (to the oc_product_special table) and everything works fine(it remembers the value in admin, as well as gets added to cart by the special price for both groups on front end.) My only problem is that it doesn't show correctly on front end. Meaning that it shows value from the special price field for both customer groups, instead of showing wholesale special price for wholesale customer. I figured out where the problem is - in the query in model/catalog/product file. I would like to know how to alter the following query, so that I can include wholesale field, because only then would I be able to show it on front end. My query is:
$query = $this->db->query("SELECT DISTINCT *, pd.name AS name, p.image, m.name AS manufacturer, (SELECT price FROM " . DB_PREFIX . "product_discount pd2 WHERE pd2.product_id = p.product_id AND pd2.customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "' AND pd2.quantity = '1' AND ((pd2.date_start = '0000-00-00' OR pd2.date_start < NOW()) AND (pd2.date_end = '0000-00-00' OR pd2.date_end > NOW())) ORDER BY pd2.priority ASC, pd2.price ASC LIMIT 1) AS discount, **(SELECT price FROM " . DB_PREFIX . "product_special ps WHERE ps.product_id = p.product_id AND ps.customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "' AND ((ps.date_start = '0000-00-00' OR ps.date_start < NOW()) AND (ps.date_end = '0000-00-00' OR ps.date_end > NOW())) ORDER BY ps.priority ASC, ps.price ASC LIMIT 1) AS special,** (SELECT points FROM " . DB_PREFIX . "product_reward pr WHERE pr.product_id = p.product_id AND customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "') AS reward, (SELECT ss.name FROM " . DB_PREFIX . "stock_status ss WHERE ss.stock_status_id = p.stock_status_id AND ss.language_id = '" . (int)$this->config->get('config_language_id') . "') AS stock_status, (SELECT wcd.unit FROM " . DB_PREFIX . "weight_class_description wcd WHERE p.weight_class_id = wcd.weight_class_id AND wcd.language_id = '" . (int)$this->config->get('config_language_id') . "') AS weight_class, (SELECT lcd.unit FROM " . DB_PREFIX . "length_class_description lcd WHERE p.length_class_id = lcd.length_class_id AND lcd.language_id = '" . (int)$this->config->get('config_language_id') . "') AS length_class, (SELECT AVG(rating) AS total FROM " . DB_PREFIX . "review r1 WHERE r1.product_id = p.product_id AND r1.status = '1' GROUP BY r1.product_id) AS rating, (SELECT COUNT(*) AS total FROM " . DB_PREFIX . "review r2 WHERE r2.product_id = p.product_id AND r2.status = '1' GROUP BY r2.product_id) AS reviews, p.sort_order FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) LEFT JOIN " . DB_PREFIX . "manufacturer m ON (p.manufacturer_id = m.manufacturer_id) WHERE p.product_id = '" . (int)$product_id . "' AND pd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "'");
The part of the query which is for special is:
(SELECT price FROM " . DB_PREFIX . "product_special ps WHERE ps.product_id = p.product_id AND ps.customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "' AND ((ps.date_start = '0000-00-00' OR ps.date_start < NOW()) AND (ps.date_end = '0000-00-00' OR ps.date_end > NOW())) ORDER BY ps.priority ASC, ps.price ASC LIMIT 1) AS special,
Thanx
I solved this problem...In case anyone gets stuck in the same place, here is what I did:
I added another line(subquery) to the query, where I defined special_wholesale like this:
SELECT wholesale FROM " . DB_PREFIX . "product_special ps WHERE ps.product_id = p.product_id AND ps.customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "' AND ((ps.date_start = '0000-00-00' OR ps.date_start < NOW()) AND (ps.date_end = '0000-00-00' OR ps.date_end > NOW())) ORDER BY ps.priority ASC, ps.wholesale ASC LIMIT 1) AS special_wholesale
as well as defined 'special_wholesale' => $query->row['special_wholesale'], in query array bellow the 'special' array element in catalog/model/catalog/product.php file inside the public function getProduct($product_id) function.
After that, I defined $special_wholesale variable in controller file for the featured products(/catalog/controller/module/featured.php).
The last thing I did was call the $product['special_wholesale']; in featured.php(/catalog/view/theme/your-theme-name/template/module/featured.tpl) file like this:
<font size="2" color="red"> <span class="price-new"><?php echo "VP:" . $product['special_wholesale']; ?></span> <span class="price-old"><?php echo "VP:". $product['wholesale']; ?></span></font></br>
The output is: striked out old wholesale price and display of special wholesale price.
I hope this can help someone. Cheers!

I want the the database query result to output the record of last seven days (referral_users )

get_results( "SELECT u.ID,
( SELECT meta_value FROM " . $wpdb -> prefix . "usermeta WHERE meta_key = 'first_name' AND user_id = u.ID ) AS firstname,
( SELECT meta_value FROM " . $wpdb -> prefix . "usermeta WHERE meta_key = 'last_name' AND user_id = u.ID ) AS lastname,
( SELECT COUNT( user_id ) FROM " . $wpdb -> prefix . "usermeta WHERE meta_key = 'user_parent' AND meta_value = u.ID ) AS referral_users
FROM
" . $wpdb -> prefix . "users AS u
WHERE
( SELECT COUNT( user_id ) FROM " . $wpdb -> prefix . "usermeta WHERE meta_key = 'user_parent' AND meta_value = u.ID ) > 0
ORDER BY referral_users DESC LIMIT 10 OFFSET 0" );

Inner SELECT can't use `u.id` which is in outer SELECT

I have the following MySQL query:
SELECT
COUNT(b.`id`) AS todayOverdue,
DATE_FORMAT(t.`created_time`, "%Y%m%d") AS days
FROM
`Bill` b
LEFT JOIN `Order` o ON b.`order_id` = o.`id`
LEFT JOIN `Trade` t ON o.`trade_id` = t.`id`
LEFT JOIN `User` u ON b.`user_id` = u.`id`
WHERE
b. `deadline` <= "' . $todayTime . '"
AND b. `deadline` >= "' . $todayDate . '"
AND b.`is_paid` = 0
AND (
SELECT
COUNT(b2.`id`)
FROM
`Bill` b2
WHERE
b2.`deadline` <= "' . $todayTime . '"
AND b2.`user_id` = u.`id`
AND b2.`is_paid` = 0
OR (
b2.`deadline` <= b2.`paid_time`
AND b2.`is_paid` = 1
)
) < 2
GROUP BY
days
Why can't the inner SELECT use u.id which is in outer SELECT?
The inner select is completely independent of the outer select. The u table is being joined in the outer select in ways that are unknown to the inner select.
When you have
AND b2.`user_id` = u.`id`
Which row in u is being compared to which row in b2? The server has no way of knowing, so you need to define a table u2 and join it in the inner select.

Avoid duplicate rows when join multiple tables

I have problem with 3 tables: first (User) contains car dealers, second and third (Order_new, Car_demo) contains two types of cars sold by dealers. I need to sum number of sales and profit for a dealer.
Unfortunately it doesn't work correctly. One of dealer sold 11 cars from Order_new and 1 from Car_demo, but when I using COUNT a get 11 from Order_new (good) and 11 from Car_demo (not good...). The same with SUM - from Car_demo I get profit x 11.
This is important fragment of code:
SELECT
d.name AS name,
COUNT(cn_renault.id) AS ren_p,
COUNT(cd_renault.id) AS ren_demo_p,
SUM(cn_renault.profit) AS cn_profit,
SUM(cd_renault.profit) AS cd_profit,
FROM User d
LEFT OUTER JOIN (
SELECT DISTINCT
cd2.id AS id,
cd2.dealer AS sale_by,
cd2.price AS price,
FROM Order_new cd2
LEFT OUTER JOIN Car car ON car.id = cd2.car_brand
WHERE DATE(cd2.' . $by . ') >= \'' . $date . '\' AND DATE(cd2.' . $by . ') < \'' . $date_end . '\' AND car.brand = \'Renault\'
GROUP BY cd2.id
) cn_renault ON cn_renault.sale_by = d.id
LEFT OUTER JOIN (
SELECT DISTINCT
cd2.id AS id,
cd2.sale_by AS sale_by,
cd2.selling_price AS price,
FROM Car_demo cd2
LEFT OUTER JOIN Car car ON car.id = cd2.car_brand
WHERE DATE(cd2.' . $by_d . ') >= \'' . $date . '\' AND DATE(cd2.' . $by_d . ') < \'' . $date_end . '\' AND cd2.sale_status >= 2 AND car.brand = \'Renault\'
GROUP BY cd2.id
) cd_renault ON cd_renault.sale_by = d.id
WHERE d.id = ' . $dealer_id . '
GROUP BY d.id
I know I can do it this way:
LEFT OUTER JOIN (
SELECT DISTINCT
COUNT(cd2.id) AS number_of,
SUM(cd2.price) AS price,
FROM Order_new cd2
LEFT OUTER JOIN Car car ON car.id = cd2.car_brand
WHERE DATE(cd2.' . $by . ') >= \'' . $date . '\' AND DATE(cd2.' . $by . ') < \'' . $date_end . '\' AND car.brand = \'Renault\'
GROUP BY cd2.dealer
) cn_renault ON cn_renault.sale_by = d.id
and it works, but I need cars id to join another tables in query...
Any ideas?