Passing column in subquery is not working - mysql

Please take a look at my query
SELECT ht_tutor.id
,(
SELECT group_concate(days)
FROM (
SELECT fkTutorId
,days
,(
CASE
WHEN endTime <= '14:00:00'
THEN '00:00:00'
WHEN TIMEDIFF(startTime, '14:00:00') < '00:00:00' && TIMEDIFF('17:00:00', endTime) < '00:00:00'
THEN TIMEDIFF('17:00:00', '14:00:00')
ELSE '00:00:00'
END
) AS intersect_time
FROM ht_tutorAvailablity
WHERE ht_tutorAvailablity.fkTutorId = ht_tutor.id
) AS avail_table
) AS days_avail
FROM ht_tutor
LIMIT 0,10
ERROR: #1054 - Unknown column 'ht_tutor.id' in 'where clause'
How can I pass ht_tutor.id their ?
If I'm passing tutor_id manually like ht_tutorAvailablity.fkTutorId = "12" than it is working fine.

Hope you need to use JOIN in your scenario. The below query will JOIN with the TUT.id = AVA.fkTutorId condition:
SELECT group_concate(days), id
FROM (
SELECT AVA.fkTutorId, AVA.days, TUT.id
CASE
WHEN AVA.endTime <= '14:00:00'
THEN '00:00:00'
WHEN TIMEDIFF(AVA.startTime, '14:00:00') < '00:00:00' && TIMEDIFF('17:00:00', AVA.endTime) < '00:00:00'
THEN TIMEDIFF('17:00:00', '14:00:00')
ELSE '00:00:00'
END AS intersect_time
FROM ht_tutorAvailablity AVA
JOIN ht_tutor TUT ON TUT.id = AVA.fkTutorId
) AS avail_table
LIMIT 0, 10

Related

CASE condition issue in Clickhouse

I wrote this code in mySQL and it runs fine there. But having some syntax issue in clickhouse db on CASE Condition :
select
BTOP.id,
BTOP.customer_id,
BTOP.brand_id,
(case when (SELECT count(customer_id) from c_bill_transaction where customer_id = BTOP.customer_id AND added_on < '2023-01-01 00:00:00') <=0 then "new" else "exiting" end) as "customer_type",
BT.id,
BT.status,
BTOP.added_on
from c_bill_transaction_online_precheckout BTOP
Left Join c_bill_transaction BT on BT.precheckout_id = BTOP.id
where BTOP.added_on > '2023-01-01 00:00:00'
Error Clickhouse is throwing :
ClickHouse exception, code: 1002, host: 127.0.0.1, port: 8123; Code: 47. DB::Exception: Missing columns: 'BTOP.customer_id' while processing query: 'SELECT count(customer_id) FROM c_bill_transaction WHERE (customer_id = BTOP.customer_id) AND (added_on < '2023-01-01 00:00:00')', required columns: 'customer_id' 'BTOP.customer_id' 'added_on', maybe you meant: ['customer_id','customer_id','added_on']: While processing (SELECT count(customer_id) FROM c_bill_transaction WHERE (customer_id = BTOP.customer_id) AND (added_on < '2023-01-01 00:00:00')) AS _subquery8: While processing ((SELECT count(customer_id) FROM c_bill_transaction WHERE (customer_id = BTOP.customer_id) AND (added_on < '2023-01-01 00:00:00')) AS _subquery8) <= 0: While processing multiIf(((SELECT count(customer_id) FROM c_bill_transaction WHERE (customer_id = BTOP.customer_id) AND (added_on < '2023-01-01 00:00:00')) AS _subquery8) <= 0, new, exiting) AS customer_type. (UNKNOWN_IDENTIFIER) (version 22.7.1.2484 (official build))
You are using a subquery that refers to a column value from the outer query. This is called a correlated subquery, and is not yet supported by clickhouse. Per https://github.com/ClickHouse/ClickHouse/issues/6697 this may become supported this year.
You can instead join c_bill_transaction and group by BTOP.id. Something like:
select
BTOP.id,
BTOP.customer_id,
BTOP.brand_id,
(case when count(BTcust.customer_id) then "new" else "exiting" end) as "customer_type",
BT.id,
BT.status,
BTOP.added_on
from c_bill_transaction_online_precheckout BTOP
Left Join c_bill_transaction BT on BT.precheckout_id = BTOP.id
left join c_bill_transaction BTcust on BTcust.customer_id=BTOP.customer_id and BTcust.added_on < '2023-01-01 00:00:00'
where BTOP.added_on > '2023-01-01 00:00:00'
group by BTOP.id

Mysql if Null or Empty String then Show N/A

Hello I'm new to mysqsl and I'm trying to display N/A if the return data is empty or NULL but my query is unrecognized statement type. What do you think is wrong with my query? wrong placement of code?
CASE when 'Earliest Time Opened' = '' or 'Earliest Time Opened' is 'Null'
then 'N/A'
ELSE
SELECT (date_format(d.date_opened, '%r') as 'Earliest Time Opened'
FROM daily_report d JOIN userinfo ui
ON d.userid= ui.id
WHERE d.date_opened >= date_sub(curdate(), interval 0 day)
AND d.survey_at_what_blh = 'Bagong Silang' AND ui.status='Employee'
ORDER BY d.date_opened DESC
limit 1
END
Use IF with ISNULL here:
SELECT IF(ISNULL(d.date_opened), 'N/A', DATE_FORMAT(d.date_opened, '%r')) AS `Earliest Time Opened`
FROM daily_report d
INNER JOIN userinfo ui ON d.userid = ui.id
WHERE
d.date_opened >= CURDATE() AND
d.survey_at_what_blh = 'Bagong Silang' AND
ui.status = 'Employee'
ORDER BY
d.date_opened DESC
LIMIT 1;
If you really wanted to use a CASE expression, then it would need to appear inside the select clause, something like this:
SELECT CASE WHEN DATE_FORMAT(d.date_opened, '%r') IS NOT NULL
THEN DATE_FORMAT(d.date_opened, '%r')
ELSE 'N/A' END AS `Earliest Time Opened`
But COALESCE is much more terse and appropriate here.

How do I multisort data that is in the future in descending order, then data in the past in ascending order?

Here is the mysql query:
SELECT `listings`.*
FROM `listings`
WHERE `listings`.`site_id` = '2'
AND `listings`.`type_id` = '2'
GROUP BY `listings`.`book_id`
ORDER BY
(CASE WHEN DATE(`listings`.`extended_end_datetime`) < DATE(CURDATE())
THEN 1
ELSE 0
END) ASC,
`listings`.`extended_end_datetime` DESC ,
`listings`.`dates_tentative` asc;
Here is how it currently sorts:
Here is how I would like it to sort:
For this sample data this will work:
order by
extended_end_datetime < curdate(),
abs(timestampdiff(minute, extended_end_datetime, now())) ,
dates_tentative
See a simplified demo.
SELECT `listings`.*
FROM `listings`
WHERE `listings`.`site_id` = '2' AND `listings`.`type_id` = '2'
GROUP BY `listings`.`book_id`
ORDER BY
(CASE WHEN DATE(`listings`.`extended_end_datetime`) < DATE(CURDATE()) THEN -1 ELSE 1 END) *
TIMESTAMPDIFF(second, DATE(`listings`.`extended_end_datetime`), DATE(CURDATE()),
`listings`.`extended_end_datetime` DESC ,
`listings`.`dates_tentative` asc
It calculate the time difference between today, and the date in the DB, and multiplies it with 1 or -1 depending on how you want to sort.

mysql return value even if it is null

I have a query that returns value if the date range is match. and if it is not match it returns nothing.
SELECT start, end
FROM (`taxemployee`)
LEFT JOIN `project_staff_assignment` ON `project_staff_assignment`.`taxemployee_id` = `taxemployee`.`id`
WHERE (start >= '2014-09-01' AND end <= '2014-09-15')
OR (end >= '2014-09-15' AND start <= '2014-09-01')
GROUP BY `taxemployee`.`id`
ORDER BY `assigned_hours`ASC
if I put this on WHERE
OR coalesce(`start`, `end`) IS NULL
it returns null values, but not includes with value
How do I return result even if it is null and with value
here is sqlfiddle
http://sqlfiddle.com/#!2/8bbe4/3
UPDATE:
Refer fiddle here : http://sqlfiddle.com/#!2/2babf/2
I am using case statement to display the date if it falls in the range and am displaying null if not.
SELECT `taxemployee`.`id`, Nickname,
case when project_staff_assignment.startdt >= '2014-09-01' THEN project_staff_assignment.STARTdt ELSE NULL END AS STARTDATE,
case when project_staff_assignment.ENDdt >= '2014-09-15' THEN project_staff_assignment.ENDdt ELSE NULL END AS ENDDATE
FROM (`taxemployee`)
LEFT JOIN `project_staff_assignment` ON `project_staff_assignment`.`taxemployee_id` = `taxemployee`.`id`
GROUP BY `taxemployee`.`id`
ORDER BY `taxemployee`.`id` ASC
ORIGINAL ANSWER:
Refer Fiddle here: http://sqlfiddle.com/#!2/8bbe4/52
SELECT `taxemployee`.`id`, Nickname, start, end
FROM (`taxemployee`)
LEFT JOIN `project_staff_assignment` ON `project_staff_assignment`.`taxemployee_id` = `taxemployee`.`id`
WHERE (start >= '2014-08-01' AND end <= '2014-08-15')
OR (end >= '2014-08-15' AND start <= '2014-09-01')
OR coalesce(`start`, `end`) IS NULL
GROUP BY `taxemployee`.`id`
ORDER BY `taxemployee`.`id` ASC;
Records were not returned because,
Value was available only for 01.08.2014 whereas, your condition was for 01.09.2014

Mysql optimization operator 'I N'

I have this query.
I want to optimization this query,because it takes more then 4.sec
![SELECT clerk_id, COUNT(*) AS num
FROM `note`
WHERE note.id IN (
SELECT note.id
FROM `note`
LEFT JOIN conn ON conn.contract_id = note.id
WHERE `type` <>4 AND `type` <>6 AND `cancelled` =0 AND `ebill` <> '' AND activated_datetime > '0000-00-00 00:00:00' AND activated_datetime >= '2011-06-13 00:00:00' AND activated_datetime <= '2011-06-21 23:59:59' AND clerk_code LIKE 'S%'
)
GROUP BY clerk_id][1]
Thanks for suggestions
I think you could write your query as a single one like this:
SELECT clerk_id, COUNT(*)
FROM `contracts`
LEFT JOIN contract_connections ON contract_connections.contract_id = contracts.id
WHERE `type` <>4 AND `type` <>6 AND `cancelled` =0 AND `ebill` <> '' AND activated_datetime >= '2011-06-13 00:00:00' AND activated_datetime <= '2011-06-21 23:59:59' AND clerk_code LIKE 'S%' GROUP BY clerk_id
Please check and see if it returns the same thing and if performance improves
SELECT clerk_id, COUNT(*) AS num
FROM `contracts`
WHERE EXISTS (
SELECT *
FROM contract_connections
WHERE `type` <>4 AND `type` <>6 AND `cancelled` =0 AND `ebill` <> '' AND activated_datetime >= '2011-06-13 00:00:00' AND activated_datetime <= '2011-06-21 23:59:59' AND clerk_code LIKE 'S%'
AND contract_connections ON contract_connections.contract_id = contracts.id
)
GROUP BY clerk_id
In case you have an index on the type column you could benefit from it changing your WHERE clause from
WHERE type <>4 AND type <>6
To
WHERE (type<4 OR type=5 OR type>6)
Also remove
activated_datetime > '0000-00-00 00:00:00'
Since you already have
activated_datetime >= '2011-06-13 00:00:00'