How to Preview Update Set Where Statement using MySQL - mysql

The query listed below works perfectly, but for the life of me I cannot figure out how to convert it to a SELECT statement and preview the results. I know how to do it when SET and WHERE are used, but the JOIN statement is messing things up. I'd appreciate suggestions.
UPDATE WA.contacts c
JOIN National.zips z
ON c.zipcode = z.zipcode
SET c.county = z.county
, c.population = z.population
, c.MA_Penetration = z.MA_Penetration
, c.MA_Eligibles = z.MA_Eligibles
WHERE state = 'WA';

Use select and from
SELECT WA.contacts.county
, National.zips.county
, WA.contacts.population
, National.zips.population
, WA.contacts.MA_Penetration
, National.zips.MA_Penetration
, WA.contacts.MA_Eligibles
, National.zips.MA_Eligibles
FROM WA.contacts
JOIN National.zips ON WA.contacts.zipcode = National.zips.zipcode
WHERE state = 'WA';

Related

I want to improve the speed of query statements, but I want to know how

When executing a query statement, the speed is very slow.
SELECT
T1.APPL_SEQ
, T1.COMP_CD
, (SELECT COMP_NM FROM tb_company WHERE COMP_CD = T1.COMP_CD) AS COMP_NM
, T1.GPROD_CD
, (SELECT GPROD_NM FROM tb_gprod WHERE GPROD_CD = T1.GPROD_CD) AS GPROD_NM
, T1.SITE_CD
, (SELECT SITE_NM FROM tb_site WHERE SITE_CD = T1.SITE_CD) AS SITE_NM
, T1.INFLOW_CD
, T1.INFLOW_URL
, T1.STATUS
, T1.REG_DTM
, DECRYPTO(T1.NAME) AS NAME
, DECRYPTO(T1.HP) AS HP
, ifnull(T1.AGE,T1.`115`) AS AGE
, ifnull(T1.GENDER,T1.`116`) AS GENDER
, ifnull(T1.MEMO,T1.`120`) AS MEMO
, ifnull(T1.`105`,T1.`124`) AS TIME
, T1.`125` AS AGE_CHILD
, T2.API_YN
, T2.API_START_DT
, T2.API_END_DT
, T2.API_CD
, T2.DATA_INFLOWCD
, T2.CONFIRM_YN
, T2.SALE_YN
, T2.SALE_PRICE
, T2.BREAKDOWN
, T2.INPUT_DATE
, T3.DIST_YN
, T3.DIST_DT
,(select ifnull((select timestampdiff(DAY, T11.REG_DTM,T1.REG_DTM) AS DIFF2REGTIME from tb_applicant T11 WHERE T11.HP = T1.HP AND T11.GPROD_CD = T1.GPROD_CD AND T11.REG_DTM < T1.REG_DTM order by T11.REG_DTM desc limit 1),-1)) AS HP2_COUNT
FROM
tb_applicant T1
LEFT JOIN mm_applicant T2
ON T1.APPL_SEQ = T2.APPL_SEQ
LEFT JOIN dist_applicant T3
ON T1.APPL_SEQ = T3.APPL_SEQ
LEFT JOIN tb_site T4
ON T4.site_cd = T1.SITE_CD and T4.comp_cd = T1.COMP_CD and T4.gprod_cd = T1.GPROD_CD
WHERE 1=1
AND T1.APPL_SEQ > 147293
AND T4.is_use = 'Y'
$Sql_Search
ORDER BY
$Sql_OrderBy
) U1
, (SELECT #ROWNUM := 0) U2
) V1";
,(select ifnull((...),-1)) AS HP2_COUNT
This is part of why it's so slow.
This query calculates the number of months difference by comparing REG_DTM when the td_applicant table has the same data for HP, GPROD, and COMP.
I don't need to get the date difference, is there any way to improve the query speed?
The main problem are those subselect in the select. As #Akina suggested, you should move them in FROM and make them as join.
They way you have done implies that each subselect is executed for each row returned by the main select.
You have 4 subselect that mean if you have 100 rows you execute 1 (main select) + (4*100) query so 401 instead of 1.
Using join allow the internal optimization engine to choose the best strategy to perform the query, in your way practically no optimization are applied.
I post a short example of how should be your query, didn't refactor the whole query since without database is a bit difficult to do it and I can easily produce a wrong query.
Notice that you select twice on tb_site with different condition, so is up to you to put the correct one.
SELECT T1.APPL_SEQ, T1.COMP_CD, T1.GPROD_CD, T1.SITE_CD
TC.COMP_NM,
TG.GPROD_NM,
TS.SITE_NM,
......
FROM tb_applicant T1
LEFT JOIN mm_applicant T2
JOIN tb_company TC on TC.COMP_CD = T1.COMP_CD
JOIN tb_gprod TG on GPROD_CD = T1.GPROD_CD
JOIN tb_site TS on TS.SITE_CD = T1.SITE_CD ON T1.APPL_SEQ = T2.APPL_SEQ
.......

Left Join not showing non match record

I have this simple mysql query with join
Select
sp.PTPK, sp.EmployeeNamePK, sp.Half, sp.TaskPK, sp.TaskAssignCompletionId, sp.SwitchDate, sp.SpendDays, /*switch_person Table*/
pro.Name as ProjectName, pro.TeamLead /*Project Table*/
From switch_person sp
LEFT JOIN projects pro
ON pro.PK = sp.PTPK
Where sp.SwitchDate = '2019-03-01'
AND sp.Half =1
It is working correctly with one issue is that project unmatched record are not showing. I mean there are some non match records (projects name) which I am not getting from the project table. I know that it should be display as I am using left join.
How about...
SELECT sp.PTPK
, sp.EmployeeNamePK
, sp.Half
, sp.TaskPK
, sp.TaskAssignCompletionId
, sp.SwitchDate
, sp.SpendDays
, pro.Name ProjectName
, pro.TeamLead
FROM projects pro
LEFT
JOIN switch_person sp
ON pro.PK = sp.PTPK
AND sp.SwitchDate = '2019-03-01'
AND sp.Half = 1
...?
Updated after you last commment.
If indeed you want to always display the project data, I think you would probably be better served with a left join. Besides that, if the problem is performance, I suggest you:
Add an index to your switch_person table
Create a Stored procedure (SP) for your query
Like this:
CREATE INDEX mydataindex ON switch_person(PTPK, SwitchDate, Half);
CREATE
PROCEDURE getmydata (IN filterdate date, IN half INT)
SELECT sp.PTPK
, sp.EmployeeNamePK
, sp.Half
, sp.TaskPK
, sp.TaskAssignCompletionId
, sp.SwitchDate
, sp.SpendDays
, pro.Name ProjectName
, pro.TeamLead
FROM projects pro
LEFT
JOIN switch_person sp
ON pro.PK = sp.PTPK
AND sp.SwitchDate = filterdate
AND sp.Half = half
ORDER BY
pro.Name;
Then, all you have to do is call that SP like this:
CALL getmydata ('2019-03-01', 1);
updated full code here

mysql - If not match rows then store in new field

The given query works fine, But i want some modification. In 3rd line i have
LEFT JOIN tbl_emp ON inventory.itemGiven = tbl_emp.Sname
This is filter the output if match.
But problem is, all the inventory.itemGiven is not present in tbl_emp.Sname. and i want, if not match then the result store in different field.
SELECT `inventory`.`ID` , `inventory`.`out_` , `inventory`.`userName` , date_format( `inventory`.`date` , '%Y-%m-%d' ) AS date, `department`.`id` , `tbl_emp`.`emp_id_number`
FROM `inventory`
LEFT JOIN `tbl_emp` ON `inventory`.`itemGiven` = `tbl_emp`.`Sname`
LEFT JOIN `department` ON `inventory`.`givenDept` = `department`.`dept`
WHERE `out_` >0
LIMIT 0 , 30
I know this is possible, please anybody help me.
Thanks in advance.
Replace tbl_emp.emp_id_number with IFNULL(tbl_emp.emp_id_number,inventory.itemGiven) in select part
SELECT `inventory`.`ID` , `inventory`.`out_` , `inventory`.`userName` , date_format( `inventory`.`date` , '%Y-%m-%d' ) AS date, `department`.`id` , `tbl_emp`.`emp_id_number`
FROM `inventory`
LEFT JOIN `tbl_emp` ON `inventory`.`itemGiven` = `tbl_emp`.`Sname`
LEFT JOIN `department` ON `inventory`.`givenDept` = `department`.`dept`
WHERE `out_` >0

query taking long time to execute and crashing the site

I am having around 2.5 lachs (250K) products and 2600 subcategories on magento application (community edition).
Query
SELECT 1 status
, e.entity_id
, e.type_id
, e.attribute_set_id
, cat_index.position AS cat_index_position
, e.name
, e.description
, e.short_description
, e.price
, e.special_price
, e.special_from_date
, e.special_to_date
, e.cost
, e.small_image
, e.thumbnail
, e.color
, e.color_value
, e.news_from_date
, e.news_to_date
, e.url_key
, e.required_options
, e.image_label
, e.small_image_label
, e.thumbnail_label
, e.msrp_enabled
, e.msrp_display_actual_price_type
, e.msrp
, e.tax_class_id
, e.price_type
, e.weight_type
, e.price_view
, e.shipment_type
, e.links_purchased_separately
, e.links_exist
, e.open_amount_min
, e.open_amount_max
, e.custom_h1
, e.awards
, e.region
, e.grape_type
, e.food_match
, e.udropship_vendor
, e.upc_barcode
, e.ean_barcode
, e.mpn
, e.size
, e.author
, e.format
, e.pagination
, e.publish_date
, price_index.price
, price_index.tax_class_id
, price_index.final_price
, IF(price_index.tier_price IS NOT NULL
, LEAST(price_index.min_price
, price_index.tier_price)
, price_index.min_price) AS minimal_price
, price_index.min_price
, price_index.max_price
, price_index.tier_price
FROM catalog_product_flat_1 e
JOIN catalog_category_product_index cat_index
ON cat_index.product_id = e.entity_id
AND cat_index.store_id = 1
AND cat_index.visibility IN(2,4)
AND cat_index.category_id = 163
JOIN catalog_product_index_price price_index
ON price_index.entity_id = e.entity_id
AND price_index.website_id = 1
AND price_index.customer_group_id = 0
GROUP
BY e.entity_id
ORDER
BY cat_index_position ASC
, cat_index.position ASC
LIMIT 15;
whenever accessing any products on this magento site it created a huge data under /tmp directory on theserver which is around 10 GB.
How can I fix this please suggest some solution.
Database size is 50 GB and server is nginx.
You are misusing GROUP BY. Please learn how it works. There's a misfeature in MySQL which allows you to misuse it. Unfortunately, queries that misuse it are very difficult to troubleshoot.
It is difficult to infer what you are trying to do from your query. When you're dealing with result sets of that size, it helps to know your intent.
You should know, if you don't already, that queries of the form
SELECT <<many columns>>
FROM large_table
JOIN another_large_table ON something
JOIN another_large_table ON something
ORDER BY some_arbitrary_column
LIMIT some_small_number
can be grossly inefficient because they have to generate an enormous result set, then sort the whole thing, then return the first results. The sort operation carries the whole result set with it. You could be instructing the MySQL server to sort a crore or two of rows (dozens of megarows).
It looks like you want the first fifteen results starting with the lowest cat_index.position value. Accordingly, you may be able to make your query faster by joining with an appropriate subset of the table you call cat_index, like so:
SELECT 1 status, many_other_columns
FROM catalog_product_flat_1 e
JOIN ( /* join only with fifteen lowest eligible position values in cat_index */
SELECT *
FROM catalog_category_product_index
WHERE store_id = 1
AND visibility IN(2,4)
AND category_id = 163
ORDER BY position ASC
LIMIT 15
) AS cat_index ON cat_index.product_id = e.entity_id
JOIN catalog_product_index_price price_index
ON price_index.entity_id = e.entity_id
AND price_index.website_id = 1
AND price_index.customer_group_id = 0
GROUP BY e.entity_id /*wrong!!*/
ORDER BY cat_index_position ASC, /* redundant!*/
cat_index.position ASC
LIMIT 15;
It's worth a try.
Are you have sufficient Hardware resources to run a big query and also please update you hardware configuration of server.

How do you debug MySQL error 1242 (Subquery returns more than 1 row)?

Is there a way to make MySQL tell which subquery gave the above error in a huge autogenerated query full of subqueries? If not, what would be your strategy for debugging it?
I would start by using either LIMIT or DISTINCT on the query and possibly sub queries.
If that didn't work I'd start going through and running each sub query individually, yes it's time consuming but I find it also helps to avoid the same problem in the future.
Example query:
UPDATE direct_orders do
SET do.dealer_id = (
SELECT d.dealer_id FROM dealers d
INNER JOIN dealer_addresses da
ON da.dealer_id = d.dealer_id
AND da.type = 'M'
AND da.status = 1
INNER JOIN dealer_details dd
ON dd.dealer_id = d.dealer_id
AND dd.status = 1
WHERE ( da.address1 LIKE CONCAT( '%', do.address1, '%' ) AND do.postal LIKE da.postal_code )
OR dd.name LIKE CONCAT( '%', do.company, '%' )
AND do.dealer_id = 0
)
This query was failing, for the same reason as the poster. One way of testing this properly is to do something like the following (note the LEFT JOIN of the table that was previously relied upon for sub-correlation):
SELECT d.dealer_id FROM dealers d
LEFT JOIN direct_orders do
ON do.dealer_id = 0
INNER JOIN dealer_addresses da
ON da.dealer_id = d.dealer_id
AND da.type = 'M'
AND da.status = 1
INNER JOIN dealer_details dd
ON dd.dealer_id = d.dealer_id
AND dd.status = 1
WHERE (da.address1 LIKE CONCAT( '%', do.address1, '%' ) AND do.postal LIKE da.postal_code )
OR dd.name LIKE CONCAT( '%', do.company, '%' )
Doing this revealed that there was in fact one record from the "direct_orders" table that return more than one "dealer_id" from the "dealers" table.