Insert into not inserting for mysql - mysql

I have below insert into statement , for mysql. When i run select statement alone it brings results.
Create statement for table is below
**create table if not exists analyze_checks(dbname varchar(50),table_name varchar(50),frag_ratio decimal, days integer,needs_optimization char(3),needs_analyzing char(3)) ENGINE=INNODB**
**insert into analyze_checks(dbname,table_name,frag_ratio, days,needs_optimization,needs_analyzing )
(select
'test' as dbname,
table_name,
frag_ratio,
days,
needs_optimization,
needs_analyzing
from
(select
table_name,
cast(frag_ratio as decimal(5,2)) as frag_ratio,
days,
case when frag_ratio > 1 then 'Yes' else 'No' end as needs_optimization,
case when days > -1 then 'Yes' else 'No' end as needs_analyzing
from (
select
t.ENGINE,
concat(t.TABLE_SCHEMA, '.', t.TABLE_NAME) as table_name,
round(t.DATA_FREE/1024/1024, 2) as data_free,
(t.data_free/(t.index_length+t.data_length)) as frag_ratio,
datediff(now(), last_update) as days
FROM information_schema.tables t
left join mysql.innodb_table_stats s on t.table_name=s.table_name
WHERE DATA_FREE > 0 ORDER BY frag_ratio DESC )d ) d
where needs_optimization='Yes' or needs_analyzing='Yes');**

There is no need to wrap the SQL statement used for the INSERT in brackets. Heck, the whole query can be simplified like this:
INSERT INTO analyze_checks(dbname,table_name,frag_ratio, days,needs_optimization,needs_analyzing )
SELECT 'test' AS dbname,
tmp.table_name,
CAST(tmp.frag_ratio AS DECIMAL(5,2)) AS frag_ratio,
tmp.days,
CASE WHEN tmp.frag_ratio > 1 THEN 'Yes' ELSE 'No' END AS needs_optimization,
CASE WHEN tmp.days > -1 THEN 'Yes' ELSE 'No' END as needs_analyzing
FROM (SELECT CONCAT(t.TABLE_SCHEMA, '.', t.TABLE_NAME) AS table_name,
ROUND(t.DATA_FREE/1024/1024, 2) AS data_free,
(t.data_free / (t.index_length + t.data_length)) AS frag_ratio,
DATEDIFF(NOW(), last_update) AS days
FROM information_schema.tables t LEFT JOIN mysql.innodb_table_stats s ON t.table_name = s.table_name
WHERE DATA_FREE > 0) tmp
WHERE 'Yes' = CASE WHEN tmp.frag_ratio > 1 THEN 'Yes'
WHEN tmp.days > -1 THEN 'Yes'
ELSE 'No' END
ORDER BY frag_ratio DESC;
Brackets and derived tables are fine when used in moderation 🤐

Related

What kind of query optimization can be done on this query?

I'm listing out orders data based on this query. This query basically pulls the recurring orders data from the table. I'm also using some dropdown and a input field to search / filter query results.
SELECT
orders.id,
parent_id,
(
SELECT
COUNT(*)
FROM
orders o
WHERE
o.parent_id = orders.id
) AS recurring_order_count,
shopify_order_type,
shopify_order_id,
shopify_order_customer_ID,
coupon_code AS coupon,
FORMAT(shopify_order_total_price, 2) AS shopify_order_total_price,
FORMAT(
shopify_order_subtotal_price,
2
) AS shopify_order_subtotal_price,
FORMAT(
shopify_order_total_line_items_price,
2
) AS shopify_order_total_line_items_price,
FORMAT(commission_amount, 2) AS commission_amount,
(
CASE WHEN is_paid = 0 THEN 'No' WHEN is_paid = 1 THEN 'Yes' ELSE 'Rejected'
END
) AS is_paid,
(
CASE WHEN is_invoice_generated = 1 THEN 'Pending' ELSE 'Invoice Generated'
END
) AS is_invoice_generated,
DATE_FORMAT(
shopify_order_created_at,
'%m-%d-%Y'
) AS shopify_order_created_at,
(
CASE WHEN is_paused = 0 THEN 'Running' ELSE 'Paused'
END
) AS is_paused,
DATE_FORMAT(
shopify_recurring_date,
'%m-%d-%Y'
) AS shopify_recurring_date
FROM
`orders`
WHERE
coupon_code LIKE '%GERALD8314%' OR shopify_order_id LIKE '%GERALD8314%' OR(
CASE WHEN is_paid = 0 THEN 'No' WHEN is_paid = 1 THEN 'Yes' ELSE 'Rejected'
END
) LIKE '%GERALD8314%' OR(
CASE WHEN is_invoice_generated = 1 THEN 'Pending' ELSE 'Invoice Generated'
END
) LIKE '%GERALD8314%' OR DATE_FORMAT(
shopify_order_created_at,
'%m-%d-%Y'
) LIKE '%GERALD8314%' OR(
CASE WHEN is_paused = 0 THEN 'Running' ELSE 'Paused'
END
) LIKE '%GERALD8314%' OR DATE_FORMAT(
shopify_recurring_date,
'%m-%d-%Y'
) LIKE '%GERALD8314%' AND DATE_FORMAT(
shopify_order_created_at,
'%Y-%m-%d'
) BETWEEN ? AND ?
GROUP BY
`id`
HAVING
parent_id = 0 AND shopify_order_type = 1
ORDER BY
`id`
DESC
LIMIT 10 OFFSET 0
Is this query optimized? Is this SELECT COUNT(*) FROM orders WHERE o.parent_id = orders.id AS recurring_order_count line most expensive in terms of query execution speed? Is there anything I should take care to improve the query speed here? Please advise.
OR and LIKE with leading wildcard are terrible for performance. Consider having a FULLTEXT index across the relevant columns. If it is practical, it will be immensely faster.
WHERE coupon_code LIKE '%GERALD8314%'
OR shopify_order_id LIKE '%GERALD8314%' OR( CASE WHEN is_paid = 0 THEN 'No' WHEN is_paid = 1 THEN 'Yes' ELSE 'Rejected' END ) LIKE '%GERALD8314%' OR( CASE WHEN is_invoice_generated = 1 THEN 'Pending' ELSE 'Invoice Generated' END ) LIKE '%GERALD8314%'
OR DATE_FORMAT( shopify_order_created_at, '%m-%d-%Y' ) LIKE '%GERALD8314%' OR( CASE WHEN is_paused = 0 THEN 'Running' ELSE 'Paused' END ) LIKE '%GERALD8314%'
OR DATE_FORMAT( shopify_recurring_date, '%m-%d-%Y' ) LIKE '%GERALD8314%'
AND DATE_FORMAT( shopify_order_created_at, '%Y-%m-%d' ) BETWEEN ? AND ?
Also, there may be surprises in the results. Note that you have
a OR b OR c AND d
which is the same as
a OR b OR (c AND d)
I suspect you wanted
(a OR b OR c) AND d
I think the GROUP BY is unnecessary. And the HAVING clauses can be merged into the WHERE.
GROUP BY `id`
HAVING parent_id = 0
AND shopify_order_type = 1
ORDER BY `id` DESC
This has multiple issues:
DATE_FORMAT( shopify_order_created_at, '%Y-%m-%d' ) BETWEEN ? AND ?
BETWEEN is "inclusive". The way you have written the query, it will include the entire ending day. This may not be what you wanted.
Assuming the variable is a DATE or DATETIME, it can be simplified to
shopify_order_created_at BETWEEN ? AND ?
There may be more tips; fix these then come back for more.

How to combine two select query with different columns

I know that union can be done to combine two queries if they have same number and type of columns. But I've a condition where I've to combine two select statement with different tables and different columns though 1 table is common in both i.e. PatientAppointment. Here are the two statements:
select p.CDRId, p.Gender,p.MRN,p.DoB as DOB,pa.AppointmentDateTime,cn.Description,ehv.ProgramName,
cn.CreatedBy as CareTeamStaffMember,cn.Profile as Role,cn.Title as Credentials,
date_format(pa.AppointmentDateTime, '%Y-%m') BillingMonth,
((case when duration like '% hour%' then substring_index(duration, ' hour', 1) * 60 else 0 end) +
(case when duration like '%min%' then substring_index(substring_index(duration, ' min', 1), ' ', -1) + 0 else 0 end)) as minutes
from Patient p inner join EnrollmentHistoryView ehv on ehv.CDRId = p.CDRId
inner join ClinicalNote cn on cn.CDRId = p.CDRId
inner join PatientAppointment pa on pa.CDRId = p.CDRId
where p.CDRId='9493b505-03b9-46a0-b009-99b34f7a5d41'
and ehv.ProgramName!='N/A'
group by p.CDRId, p.Gender, p.MRN, p.Dob, pa.AppointmentDateTime,cn.Description,cn.CreatedBy,cn.Profile,cn.Title,pa.Duration,ehv.ProgramName
UNION
SELECT AppointmentDateTime,
duration,
minutes,
CASE WHEN #prev_month != BillingMonth
THEN total >= 20
WHEN #prev_total < 20
THEN 1
ELSE 0
END 99457Elig,
CASE WHEN #prev_month != BillingMonth
THEN total >= 40
WHEN #prev_total < 40
THEN 1
ELSE 0
END 99458Elig,
#prev_month := BillingMonth BillingMonth,
#prev_total := total total
FROM (select AppointmentDateTime,
duration,
#cur_dur := ((case when duration like '% hour%' then substring_index(duration, ' hour', 1) * 60 else 0 end) +
(case when duration like '%min%' then substring_index(substring_index(duration, ' min', 1), ' ', -1) + 0 else 0 end)) as minutes,
CASE WHEN #year_month = date_format(AppointmentDateTime, '%Y-%m')
THEN #cum_sum := #cum_sum + #cur_dur
ELSE #cum_sum := #cur_dur
END total,
#year_month := date_format(AppointmentDateTime, '%Y-%m') BillingMonth
from PatientAppointment, (SELECT #year_month:='', #cum_sum:=0, #cur_dur:=0) variables
ORDER BY AppointmentDateTime) subquery,
(SELECT #prev_month:=0, #prev_total:=0) variable
ORDER BY AppointmentDateTime
The query is too complex and I can't create the data set also. Please help me with the approach. Give me some suggestion at least. I'll try it myself.
Consider your first query as Query1 and second query as Query2, you can use simple join between these two.
As you said PatientAppointment table is common in both, use its primary key(CDRId) as joining between these two. So your query would look like.
SELECT *
FROM ( Query1 ) AS table1
INNER JOIN ( Query2) AS table2 ON table1.CDRId = table2.CDRId;

Only fetch records with in date range

I have created below query :
SELECT
UserID, Username,FirstName, LastName, SUM(CAST(Pass as SIGNED)) Pass,
SUM(CAST(Fail as SIGNED)) Fail,SUM(CAST(Others as SIGNED)) Others,
CAST(SUM(Pass+Fail+Others) as SIGNED) TotalExecutions, CreatedDate
FROM
(
SELECT tbl_users.UserID, tbl_users.Username, tbl_users.FirstName, tbl_users.LastName, tbl_executionaudit.CreatedDate,
CASE WHEN tbl_executionaudit.Status ='5' THEN count(*) ELSE '' END as `Pass`,
CASE WHEN tbl_executionaudit.Status = '6' THEN count(*) ELSE '' END as `Fail`,
CASE WHEN tbl_executionaudit.Status !='5' and tbl_executionaudit.Status !='6' THEN count(*) ELSE '' END as `Others`
FROM tbl_users
INNER JOIN tbl_useraccounts on tbl_users.UserID=tbl_useraccounts.UserID
INNER JOIN tbl_executionaudit on tbl_executionaudit.UserAccountID=tbl_useraccounts.UserAccountID
WHERE DATE(tbl_executionaudit.CreatedDate) BETWEEN '2019-06-15' AND '2019-08-30' or tbl_executionaudit.Status in(3,4,5,6,7,8)
GROUP by tbl_users.UserID, tbl_users.Username, tbl_executionaudit.Status, tbl_executionaudit.CreatedDate
) subquery
GROUP BY UserID, Username
Query link : external link to GDrive
I want to fetch from BETWEEN '2019-06-15' AND '2019-08-30' .

SQL query to DQL

I have a big query and I want to add a subquery to get the availability of accommodation-rooms.
This is the SQL subquery:
,(SELECT (CASE WHEN count(_days) > 0 THEN 'yes' ELSE 'No' END) as available
FROM
(
SELECT count(rtd.room_type_id) as _days
FROM room_type_day as rtd
WHERE rtd.date IN ('2018-06-20', '2018-06-21', '2018-06-22')
GROUP BY rtd.room_type_id
HAVING COUNT(rtd.room_type_id) = 3
) as sub) as availability
Can anyone tell me how to convert this SQL in DQL?
Thak you
EDIT
I try with this changes but the response is null every time:
,(SELECT (CASE WHEN count(rtd.roomType) > 0 THEN 'yes' ELSE 'no' END)
FROM AppBundle:RoomTypeDayCancelationConditionAccommodation as RTDCCA2
LEFT JOIN RTDCCA2.roomTypeDay as rtd
WHERE rtd.date IN ('2018-06-20', '2018-06-21', '2018-06-22')
GROUP BY rtd.roomType
HAVING COUNT(rtd.roomType) = 3
) as disponible

If else condition in mysql query

How can I use if and else condition in mysql query. Here is my query.
SELECT CASE WHEN IDParent < 1 THEN 'no' ELSE 'yes' END AS ColumnName FROM tableName;
Try this;) Take a look of mysql-if-function.
SELECT If(IDParent < 1, 'no', 'yes') AS ColumnName FROM tableName;