Currently we have to run the following SQL Query to find all customers that have not been assigned access to a downloadable product.
SELECT c.entity_id as customer_id, dp.purchased_id as purchased_id
FROM magento_dev.sales_order as so
JOIN magento_dev.sales_order_address as soa on so.entity_id = soa.parent_id
JOIN magento_dev.customer_entity as c on c.email = soa.shipping_email
JOIN magento_dev.downloadable_link_purchased as dp on so.increment_id = dp.order_increment_id
where
so.customer_id = 12345 and
so.created_at > '2021-04-01' and
soa.shipping_email is not null and
dp.customer_id != c.entity_id
;
Which produces this:
customer_id purchased_id
99999 55555
Then with the results, we manually have to go through, and for each customer_id, and purchase_id run the following query:
UPDATE `magento_dev`.`downloadable_link_purchased` SET `customer_id` = '99999' WHERE (`purchased_id` = '55555');
So for the SQL Ninja's, any suggestions on how to make this a single query that finds the mismatched assignments and then does the update/insert at once?
Just put all the JOINs in the UPDATE query.
UPDATE `magento_dev`.`downloadable_link_purchased` AS dp1
JOIN magento_dev.sales_order as so
JOIN magento_dev.sales_order_address as soa on so.entity_id = soa.parent_id
JOIN magento_dev.customer_entity as c on c.email = soa.shipping_email
JOIN magento_dev.downloadable_link_purchased as dp
ON so.increment_id = dp.order_increment_id
AND dp.customer_id != c.entity_id
AND dp1.purchased_id = dp.purchased_id
SET dp1.customer_id = c.entity_id
where
so.customer_id = 12345 and
so.created_at > '2021-04-01' and
soa.shipping_email is not null
Can be done like sub query and join with the table which should be updated,
UPDATE
magento_dev.downloadable_link_purchased F
JOIN
(SELECT c.entity_id as customer_id, dp.purchased_id as purchased_id
FROM magento_dev.sales_order as so
JOIN magento_dev.sales_order_address as soa on so.entity_id = soa.parent_id
JOIN magento_dev.customer_entity as c on c.email = soa.shipping_email
JOIN magento_dev.downloadable_link_purchased as dp on so.increment_id = dp.order_increment_id
WHERE
so.customer_id = 12345 and
so.created_at > '2021-04-01' and
soa.shipping_email is not null and
dp.customer_id != c.entity_id) S
ON F.purchased_id = S.purchased_id
SET F.customer_id = S.customer_id;
Related
i have this query:
select b.observation, b.created_date (datetime field)
FROM logistics_wms.reception_documents a
join logistics_wms.reception b on a.reception_id = b.id
join logistics_wms.document c on a.documents_id = c.id
join logistics_wms.document_type d on d.id = c.document_type_id
join logistics_wms.document_line e on c.id = e.document_id
join logistics_wms.product g on e.product_id = g.id
where b.status = 'SUBMITTED'
and b.created_date >= '2020-04-01 00:00:00'
i used '2020-04-01' too
And the result is:
but if i used:
select b.observation, b.created_date (datetime field)
FROM logistics_wms.reception_documents a
join logistics_wms.reception b on a.reception_id = b.id
join logistics_wms.document c on a.documents_id = c.id
join logistics_wms.document_type d on d.id = c.document_type_id
join logistics_wms.document_line e on c.id = e.document_id
join logistics_wms.product g on e.product_id = g.id
where b.status = 'SUBMITTED'
and b.created_date >= '2020-04-15 00:00:00'
i used '2020-04-15' too
the result is:
why when i select 2020-04-01 the query doesn´t get the last two records of the second query??!!
Please help me
Thank you
Given the fact that time has no importance in your case (00:00:00), it is much simpler to use MySQL DATE function in your filter. Can you try using :
where b.status = 'SUBMITTED' and DATE(b.created_date) >= '2020-04-01'
and
where b.status = 'SUBMITTED' and DATE(b.created_date) >= '2020-04-15'
i am developing a LMS system for an institute
and i am trying to develop a recovery report on the end of month
the report contains student name total fee package, total received, total receiveable, current month pending installment
here is the installment data of a student with his admission id
and this is the ledger data from where ican pick the fee package and total receiveable fees
and i am using this query for recovery report
SELECT
SUM(l.dr)-SUM(l.cr) as sum_remaining,
f.dr as fee_package,
SUM(i.payment) as this_month_install,
a.reg_id, s.fname
FROM
ledger l, ledger f, student_data s,
admissions a LEFT OUTER JOIN installments i ON a.admissionid = i.admissionid
WHERE
a.admissionid = '58ac4b5421488' AND
a.reg_id = s.reg_id AND
l.reference = '58ac4b5421488' AND
l.details <> 'registration fee' AND
f.reference = '58ac4b5421488' AND
f.details = 'Fee Package' AND
i.install_no <> '1' AND
MONTH(i.pay_date) = '04' AND
YEAR(i.pay_date) = '2017'
GROUP BY a.admissionid
and its giving the result like this
but the result should be like
sum_remaining = 10000
and this_month_install = 10000
please help me to sort out this problem
Thanks in advance
you should start from admission and use inner join for the others table (left join for installments)
SELECT
SUM(l.dr)-SUM(l.cr) as sum_remaining,
f.dr as fee_package,
SUM(i.payment) as this_month_install,
a.reg_id,
s.fname
FROM admissions a
Inner JOIN ledger f ON f.reference = a.admissionid AND f.details = 'Fee Package'
INNER JOIN ledger l ON l.reference = a.admissionid AND l.details <> 'registration fee'
INNER JOIN student_data s ON a.reg_id = s.reg_id
LEFT JOIN installments i ON a.admissionid = i.admissionid AND i.install_no <> '1'
WHERE a.admissionid = '58ac4b5421488'
AND MONTH(i.pay_date) = '04'
AND YEAR(i.pay_date) = '2017'
GROUP BY a.admissionid
you have two row in installments table that match .. try filter just one
SELECT
SUM(l.dr)-SUM(l.cr) as sum_remaining,
f.dr as fee_package,
SUM(i.payment) as this_month_install,
a.reg_id,
s.fname
FROM admissions a
Inner JOIN ledger f ON f.reference = a.admissionid AND f.details = 'Fee Package'
INNER JOIN ledger l ON l.reference = a.admissionid AND l.details <> 'registration fee'
INNER JOIN student_data s ON a.reg_id = s.reg_id
LEFT JOIN installments i ON a.admissionid = i.admissionid
AND i.install_no not in ( '1', '2')
WHERE a.admissionid = '58ac4b5421488'
AND MONTH(i.pay_date) = '04'
AND YEAR(i.pay_date) = '2017'
GROUP BY a.admissionid
i have done this with a sub query
thanks all
select a.admissionid, s.fname,
sum(l.dr)-SUM(l.cr) as sum_remaining, i.*,
f.dr as fee_package from student_data s,
ledger l, ledger f, admissions a
RIGHT outer join (select admissionid,
sum(payment) as this_month_install
from
installments g where g.install_no <> '1' and MONTH(g.pay_date) = '04' and YEAR(g.pay_date) = '2017' group by g.admissionid) i
ON
i.admissionid = a.admissionid where a.reg_id = s.reg_id and
a.status = 'studying' and a.course = 'PH' and
a.campus = 'CIFSD01' and l.reference = a.admissionid and
l.details <> 'registration fee' and f.reference = a.admissionid
and f.details = 'Fee Package' GROUP BY a.std_id
I've got the query below that's pulling data from a number of tables to create an update:
UPDATE en_inter.subscribers_data AS sd
inner join en_inter.list_subscribers AS ls on sd.subscriberid = ls.subscriberid
LEFT JOIN (
SELECT pd1.email_address,COUNT(pd1.email_address) AS NumDowns
FROM email.papr_down pd1
INNER JOIN email.papr_data pd2 on pd1.paper_id = pd2.id
INNER JOIN email.papr_subj ps on ps.id = pd2.subject
INNER JOIN email.papr_exam pe on pe.id = pd2.exam
INNER JOIN email.papr_levl pl on pl.id = pd2.level
WHERE pd2.exam = 1
and pd2.level = 4
GROUP BY email_address
) AS downs ON downs.email_address = ls.emailaddress
SET sd.data = ifnull(downs.NumDowns,1)
WHERE sd.fieldid = 33;
It works fine but when there are plenty of records in papr_down then it takes ages to process. Any ideas about how it can be optimized?
What I think is the join between the emailAddress is the issue here, you can try out with the join with the Id's.
If you provide us the screen shot of the below query ::
EXPLAIN Select * from
en_inter.subscribers_data AS sd
inner join en_inter.list_subscribers AS ls on sd.subscriberid = ls.subscriberid
LEFT JOIN (
SELECT pd1.email_address,COUNT(pd1.email_address) AS NumDowns
FROM email.papr_down pd1
INNER JOIN email.papr_data pd2 on pd1.paper_id = pd2.id
INNER JOIN email.papr_subj ps on ps.id = pd2.subject
INNER JOIN email.papr_exam pe on pe.id = pd2.exam
INNER JOIN email.papr_levl pl on pl.id = pd2.level
WHERE pd2.exam = 1
and pd2.level = 4
GROUP BY email_address
) AS downs ON downs.email_address = ls.emailaddress
WHERE sd.fieldid = 33
As I know we should use joins only for the columns which are preset in SELECT clause and for other joins we should implement using WHERE clause
Please try following query:
UPDATE en_inter.subscribers_data AS sd
inner join en_inter.list_subscribers AS ls
on sd.subscriberid = ls.subscriberid
LEFT JOIN (
SELECT pd1.email_address,COUNT(pd1.email_address) AS NumDowns
FROM email.papr_down AS pd1
INNER JOIN email.papr_data AS pd2 on pd1.paper_id = pd2.id
WHERE
email.papr_exam.id in (select exam from email.papr_data where exam = 1)
AND
email.papr_levl.id in (select level from email.papr_data where level = 4 )
AND
email.papr_subj.id in (select subject from email.papr_data)
GROUP BY email_address
) AS downs ON downs.email_address = ls.emailaddress
SET sd.data = ifnull(downs.NumDowns,1)
WHERE sd.fieldid = 33;
I can not execute this at my machine since i don't have the schema
Hi I have run into a dilemma, I am doing this query:
SELECT GROUP_CONCAT(DISTINCT(ca.category_name) SEPARATOR ', ') AS categories, pr.promo_name, pr.add_value_text, c.contract_id, c.cmeal_plan, c.cmin_markup, c.civa, c.tax_include, c.hotel_id, hi.hname, hi.hstars, im.image_file, pl.plan_name, ra.price
FROM contracts AS c
INNER JOIN hotel_info AS hi ON hi.hotel_id = c.hotel_id AND hi.destination_id = '6460'
INNER JOIN images AS im ON im.foreign_id = hi.hotel_id
INNER JOIN meal_plan AS pl ON pl.plan_code = c.cmeal_plan AND pl.lang = '1'
INNER JOIN hotel_categories AS hc ON hc.hotel_id = hi.hotel_id
INNER JOIN categories AS ca ON ca.category_code = hc.category_code AND ca.lang = '1'
LEFT JOIN
(SELECT
r.hotel_id, AVG(r.double) AS price
FROM
rates AS r ) AS ra
ON ra.hotel_id = hi.hotel_id
LEFT JOIN promotions AS pr ON pr.hotel_id = hi.hotel_id AND FIND_IN_SET(c.contract_id, pr.contract_id) > 0 AND pr.book_start <= '2012-11-01' AND pr.book_end >= '2012-11-02' AND travel_start <= '2012-11-23' AND travel_end >= '2012-11-30' AND pr.lang = '1'
WHERE c.cstart <= '2012-11-01' AND c.cend >= '2012-11-01'
AND hi.status = '1'
AND im.type ='1'
GROUP BY hi.hotel_id
I am getting all the desired results except for the sub select query.. each hotel has a price but it is only giving me back one result and the rest are all null. Is there an error in my query? If any additional information is needed please let me know and thank you in advance for any help!
You are missing the GROUP BY in your subquery, so MySQL will only return one-value. If you want all hotel_id's then you need to GROUP BY that field:
SELECT GROUP_CONCAT(DISTINCT(ca.category_name) SEPARATOR ', ') AS categories,
pr.promo_name,
pr.add_value_text,
c.contract_id,
c.cmeal_plan,
c.cmin_markup,
c.civa,
c.tax_include,
c.hotel_id,
hi.hname,
hi.hstars,
im.image_file,
pl.plan_name,
ra.price
FROM contracts AS c
INNER JOIN hotel_info AS hi
ON hi.hotel_id = c.hotel_id
AND hi.destination_id = '6460'
INNER JOIN images AS im
ON im.foreign_id = hi.hotel_id
INNER JOIN meal_plan AS pl
ON pl.plan_code = c.cmeal_plan
AND pl.lang = '1'
INNER JOIN hotel_categories AS hc
ON hc.hotel_id = hi.hotel_id
INNER JOIN categories AS ca
ON ca.category_code = hc.category_code
AND ca.lang = '1'
LEFT JOIN
(
SELECT r.hotel_id, AVG(r.double) AS price
FROM rates AS r
GROUP BY r.hotel_id <-- add a GROUP BY hotel_id then you will get avg() for each hotel
) AS ra
ON ra.hotel_id = hi.hotel_id
LEFT JOIN promotions AS pr
ON pr.hotel_id = hi.hotel_id
AND FIND_IN_SET(c.contract_id, pr.contract_id) > 0
AND pr.book_start <= '2012-11-01'
AND pr.book_end >= '2012-11-02'
AND travel_start <= '2012-11-23'
AND travel_end >= '2012-11-30'
AND pr.lang = '1'
WHERE c.cstart <= '2012-11-01'
AND c.cend >= '2012-11-01'
AND hi.status = '1'
AND im.type ='1'
GROUP BY hi.hotel_id
I have a query that I can't seem to manipulate to work in a SUM function in MySQL:
Here is what I want:
UPDATE account_seeds AS a
INNER JOIN b AS b ON b.accountID = a.accountID AND a.areaID = b.areaID
INNER JOIN b_seed AS s ON s.buildingID = b.buildingID
INNER JOIN seed_class AS c ON c.seedID = s.seedID
SET a.amount = a.amount + SUM(s.amount)
WHERE b.status='active' AND a.seedID = s.seedID
Now it obviously won't let me use the SUM in the update without separating it. I have tried joining select queries but can't quite get my head around it. The basic premise being that I have multiple buildings(rows) that has a seed value that will increase total seeds of that type in the area for a particular account. Without the sum it only updates one of the buildings that has a matching seed value
UPDATE
account_seeds AS a
INNER JOIN
( SELECT b.accountID, b.areaID, s.seedID
, SUM(s.amount) AS add_on
FROM b AS b
INNER JOIN b_seed AS s
ON s.buildingID = b.buildingID
INNER JOIN seed_class AS c
ON c.seedID = s.seedID
WHERE b.status = 'active'
GROUP BY b.accountID, b.areaID, s.seedID
) AS g
ON g.accountID = a.accountID
AND g.areaID = a.areaID
AND g.seedID = a.seedID
SET
a.amount = a.amount + g.add_on ;
Maybe you can use a nested query:
UPDATE account_seeds AS a
INNER JOIN b AS b ON b.accountID = a.accountID AND a.areaID = b.areaID
INNER JOIN b_seed AS s ON s.buildingID = b.buildingID
INNER JOIN seed_class AS c ON c.seedID = s.seedID
SET a.amount = a.amount + (SELECT SUM(amount) FROM b_seed)
WHERE b.status='active' AND a.seedID = s.seedID
Can you try that?