MySQL query hanging - mysql

I have a mysql query, which runs however it just hangs and doesn't stop. I'm unsure where the query is breaking.
SELECT
TIMESTAMPDIFF(SECOND, '1970-01-01 00:00:00', f.Datestamp) AS Epoch,
f.value AS `Usage`,
q.Name AS Quantity,
q.QuantityID,
units,
PrimeDataItem,
dd.Description
FROM SourceChannels c
JOIN UsageHhourly f ON c.ChanID = f.ChanID
JOIN Quantities q ON c.QuantityID = q.QuantityID
LEFT JOIN DigitalDescriptions dd ON ((c.DigitalDescriptionID = dd.DigitalDescriptionID)
AND f.value = (CASE WHEN dd.Value REGEXP '^[0-9]' = 1 then dd.Value ELSE -1 END))
WHERE
c.EquipmentID = 1496
AND f.DateStamp >= '2016-12-28 00:00:00'
AND f.DateStamp < '2017-01-04 00:00:00'
ORDER BY q.QuantityID, f.datestamp

The question does not provide more en-lighting information. Try to alter your query like in the below example.
SELECT
TIMESTAMPDIFF(SECOND, '1970-01-01 00:00:00', `f`.`Datestamp`) AS `Epoch`,
`f`.`value` AS `Usage`,
`q`.`Name` AS `Quantity`,
`q`.`QuantityID`,
`c`.`units`,
`c`.`PrimeDataItem`,
`dd`.`Description`
FROM `SourceChannels` `c`
INNER JOIN `UsageHhourly` `f` ON `c`.`ChanID` = `f`.`ChanID`
INNER JOIN `Quantities` `q` ON `c`.`QuantityID` = `q`.`QuantityID`
LEFT JOIN `DigitalDescriptions` `dd` ON `c`.`DigitalDescriptionID` = `dd`.`DigitalDescriptionID`
WHERE
`f`.`value` = IF((dd.Value REGEXP '^[0-9]'),1,-1)
AND `c`.`EquipmentID` = 1496
AND `f`.`DateStamp` BETWEEN '2016-12-28 00:00:00' AND '2017-01-04 00:00:00'
ORDER BY `q`.`QuantityID`, `f`.`datestamp`;

Related

Select Between 2 dates but also select NULL values

I'm trying to run a query where I select dates between 2 values
OR ( `order_products`.`deleted_at` BETWEEN
'2021-01-01 00:00:00' AND '2021-07-28 23:59:59' )
But I also need to collect order_products with NULL values.
Is this at all possible, as when I put an
OR `order_products`.`deleted_at` IS NULL
Into my code, It seems to just return absolutley everything in the database :-(
My current code, for context is :
SELECT
`orders`.`id`,
`orders`.`reference`,
`orders`.`order_date`,
`orders`.`cancellation_date`,
`order_products`.`description`,
`order_products`.`st_code`,
`order_products`.`supplier_stock_code`,
`order_products`.`status`,
`order_products`.`deleted_at`,
`supplier`.`name`,
order_invoice.created_at AS credit_date,
fitters.account_number AS fitter_account_number,
fitters.name AS fitter
FROM `order_products`
LEFT JOIN `orders` ON (`orders`.`id` = `order_products`.`order_id`)
LEFT JOIN `supplier` ON (`order_products`.`supplier_id` = `supplier`.`id`)
LEFT JOIN `fitters` ON (`orders`.`fitter_id` = `fitters`.`id`)
JOIN `order_invoice` ON (`order_invoice`.`order_id` = `orders`.`id`)
WHERE `cancellation_date` IS null
AND `cancellation_date` BETWEEN '2021-01-01 00:00:00' AND '2021-07-28 23:59:59'
AND `order_invoice`.`status` = 'approved'
OR (`order_products`.`deleted_at` BETWEEN '2021-01-01 00:00:00'
OR `order_products`.`deleted_at` IS NULL
AND '2021-07-28 23:59:59')
AND `order_products`.`product_type` = 'product'
ORDER BY `orders`.`id` ASC
Your syntax is off. You need:
WHERE order_products.deleted_at >= '2021-01-01' AND
order_products.deleted_at < '2021-07-29' OR
order_products.deleted_at IS NULL
Note that I wrote the datetime check using date inequalities, which seems cleaner to me. Also, we don't need any extra parentheses here as AND has higher precedence than OR.
Please try changing the where condition to
WHERE cancellation_date IS null
AND cancellation_date BETWEEN '2021-01-01 00:00:00' AND '2021-07-28 23:59:59'
AND order_invoice.status = 'approved'
OR (order_products.deleted_at IS NULL OR order_products.deleted_at BETWEEN '2021-01-01 00:00:00' AND '2021-07-28 23:59:59')
AND order_products.product_type = 'product'

SQL where query to a first row of IN condition

I have this SQL query:
SELECT (CASE WHEN count(_days) > 0 THEN 'yes' ELSE 'No' END) as availability
FROM (
SELECT count(roomTypeDay2.room_type_id) as _days
FROM room_type_day as roomTypeDay2
LEFT JOIN room_type as roomType2 on roomTypeDay2.room_type_id = roomType2.id
WHERE roomType2.accommodation_id=3
AND roomTypeDay2.date IN ( '2018-06-09 00:00:00','2018-06-10 00:00:00','2018-06-11 00:00:00')
GROUP BY roomTypeDay2.room_type_id
HAVING COUNT(roomTypeDay2.room_type_id) = 3
) as disponible
This works fine, but now, I want to filter if the first date row (2018-06-09 00:00:00) have
"min_night_stay <= 3 and release_days <=2"
parameters, but I don't know how doing it.
I try adding these lines to a query:
AND (roomTypeDay2.date = '2018-06-09 00:00:00' and
roomTypeDay2.min_night_stay <= 3 AND roomTypeDay2.release_days <= 2)
But this is not correct query.
UDPATE
SELECT (CASE WHEN count(_days) > 0 THEN 'yes' ELSE 'No' END) as availability
FROM (
SELECT count(roomTypeDay2.room_type_id) as _days
FROM room_type_day as roomTypeDay2
LEFT JOIN room_type as roomType2 on roomTypeDay2.room_type_id = roomType2.id
AND roomType2.accommodation_id=3
WHERE roomTypeDay2.date IN ( '2018-06-09 00:00:00','2018-06-10 00:00:00','2018-06-11 00:00:00')
GROUP BY roomTypeDay2.room_type_id
HAVING COUNT(roomTypeDay2.room_type_id) = 3
) as disponible
Solution
SELECT (CASE WHEN count(_days) > 0 THEN 'yes' ELSE 'No' END) as availability
FROM (
SELECT count(roomTypeDay2.room_type_id) as _days
FROM room_type_day as roomTypeDay2
LEFT JOIN room_type as roomType2 on roomTypeDay2.room_type_id = roomType2.id
WHERE roomType2.accommodation_id=3
AND roomTypeDay2.num_rooms_available > 0
AND (roomTypeDay2.date = '2018-06-12 00:00:00' AND roomTypeDay2.min_night_stay <= 2 AND roomTypeDay2.release_days <= 2 )
OR roomTypeDay2.date IN ( '2018-06-13 00:00:00','2018-06-14 00:00:00')
GROUP BY roomTypeDay2.room_type_id
HAVING COUNT(roomTypeDay2.room_type_id) = 3
) as disponible
This is your WHERE clause:
WHERE roomTypeDay2.date IN ('2018-06-09 00:00:00',
'2018-06-10 00:00:00',
'2018-06-11 00:00:00')
Now for the first date you want additional criteria. Use AND and ORwith parentheses for this:
WHERE
(
roomTypeDay2.date = '2018-06-09 00:00:00'
AND
roomTypeDay2.min_night_stay <= 3
AND
roomTypeDay2.release_days <= 2
)
OR
roomTypeDay2.date IN ('2018-06-10 00:00:00','2018-06-11 00:00:00')
SELECT
(
CASE WHEN count(_days) > 0 THEN 'yes' ELSE 'No' END
) as availability
from
(
SELECT
count(roomTypeDay2.room_type_id) as _days
FROM
room_type_day as roomTypeDay2
LEFT JOIN room_type as roomType2 on roomTypeDay2.room_type_id = roomType2.id
AND roomType2.accommodation_id = 3
WHERE
roomTypeDay2.date IN ('2018-06-10 00:00:00', '2018-06-11 00:00:00')
GROUP BY
roomTypeDay2.room_type_id
HAVING
COUNT(roomTypeDay2.room_type_id) = 3
union
SELECT
count(roomTypeDay2.room_type_id) as _days
FROM
room_type_day as roomTypeDay2
LEFT JOIN room_type as roomType2 on roomTypeDay2.room_type_id = roomType2.id
AND roomType2.accommodation_id = 3
WHERE
roomTypeDay2.date = '2018-06-09 00:00:00'
and roomTypeDay2.min_night_stay <= 3
AND roomTypeDay2.release_days <= 2
GROUP BY
roomTypeDay2.room_type_id
HAVING
COUNT(roomTypeDay2.room_type_id) = 3
) disponible

Query using group by month

I have problem with the query using group by month. This query returns total_revenue per month. but if month of year doesn't contain any data then total_revnue is increased unnecessarily.
SELECT COUNT(CT.cumTxnReportId),
CT.cumTxnReportId,
CT.ticketNum,
DATE_FORMAT(CT.exitDateTimeUtc,'%m-%Y'),
sum(netAmount) AS total_revenue,
D.name,
HOUR(CT.entranceDateTimeUtc) AS entryHour,
HOUR(CT.exitDateTimeUtc) AS exitHour,
CT.entranceDateTimeUtc,
CT.exitDateTimeUtc,
CT.netAmount AS netAmount,
CT.grossAmount,
CT.discountAmount,
CT.rate,
CT.txnType,
CT.ticketType,
CT.txnNum,
CT.numDiscounts
FROM Parkloco.ParkingArea PA
JOIN IParcPro.Device D ON PA.id = D.parkingAreaId
JOIN Parkloco.RateCard RC ON PA.id = RC.parkingAreaId
JOIN IParcPro.CumTxn CT ON D.id = CT.deviceId
WHERE PA.uuid = '27d842c1-7057-11e6-a0eb-1245b0d35d23'
AND (CT.txnType = 'Allowed'
OR CT.txnType = 'Add'
OR CT.txnType = 'Normal'
OR CT.txnType = 'Offline'
OR CT.txnType = 'Repay')
AND ((CT.entranceDateTimeUtc >= '2016-08-01 00:00:00'
AND CT.exitDateTimeUtc <= '2017-04-31 23:59:59'))
AND (RC.state = 'active'
OR RC.state = 'archived')
AND RC.fromDateTimeUtc <= '2017-04-31 23:59:59'
AND (RC.thruDateTimeUtc IS NULL
OR RC.thruDateTimeUtc >= '2016-08-01 00:00:00')
AND (TIMESTAMPDIFF (SECOND, CT.entranceDateTimeUtc, CT.exitDateTimeUtc) >= '0' * 60)
AND (TIMESTAMPDIFF (SECOND, CT.entranceDateTimeUtc, CT.exitDateTimeUtc) < '1441' * 60)
AND CT.numDiscounts=0
AND CT.ticketNum !=0
GROUP BY DATE_FORMAT(CT.exitDateTimeUtc,'%m-%Y')
but when I am increasing the range month - at that point of time I am getting unneccessary increment in total_revenue
SELECT COUNT(CT.cumTxnReportId),
CT.cumTxnReportId,
CT.ticketNum,
DATE_FORMAT(CT.exitDateTimeUtc,'%m-%Y'),
sum(netAmount) AS total_revenue,
D.name,
HOUR(CT.entranceDateTimeUtc) AS entryHour,
HOUR(CT.exitDateTimeUtc) AS exitHour,
CT.entranceDateTimeUtc,
CT.exitDateTimeUtc,
CT.netAmount AS netAmount,
CT.grossAmount,
CT.discountAmount,
CT.rate,
CT.txnType,
CT.ticketType,
CT.txnNum,
CT.numDiscounts
FROM Parkloco.ParkingArea PA
JOIN IParcPro.Device D ON PA.id = D.parkingAreaId
JOIN Parkloco.RateCard RC ON PA.id = RC.parkingAreaId
JOIN IParcPro.CumTxn CT ON D.id = CT.deviceId
WHERE PA.uuid = '27d842c1-7057-11e6-a0eb-1245b0d35d23'
AND (CT.txnType = 'Allowed'
OR CT.txnType = 'Add'
OR CT.txnType = 'Normal'
OR CT.txnType = 'Offline'
OR CT.txnType = 'Repay')
AND ((CT.entranceDateTimeUtc >= '2016-08-01 00:00:00'
AND CT.exitDateTimeUtc <= '2017-07-31 23:59:59'))
AND (RC.state = 'active'
OR RC.state = 'archived')
AND RC.fromDateTimeUtc <= '2017-07-31 23:59:59'
AND (RC.thruDateTimeUtc IS NULL
OR RC.thruDateTimeUtc >= '2016-08-01 00:00:00')
AND (TIMESTAMPDIFF (SECOND, CT.entranceDateTimeUtc, CT.exitDateTimeUtc) >= '0' * 60)
AND (TIMESTAMPDIFF (SECOND, CT.entranceDateTimeUtc, CT.exitDateTimeUtc) < '1441' * 60)
AND CT.numDiscounts=0
AND CT.ticketNum !=0
GROUP BY DATE_FORMAT(CT.exitDateTimeUtc,'%m-%Y')
output such as :
can anyone help me on this? Thanks in advance if you could let me know.
Despite MySQL allow this weird group by rules, in my opinion, you should to avoid use it. I explain, usually, all select clause non aggregate fields should appear on group by clause:
select a,b,c, sum(z)
from t
group by a,b,c
vs
select a,b,c, sum(z)
from t
group by a #<--- MySQL allow this!
Then, if b and c are not in group by, how MySQL figure up the right fields to be selected? Like this on <5.6:
The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate.
In my opinion, in your query has no sense: Look entryHour and total_revenue. One is for an entry the other one is for all month.
I guess you should to rethink the hole sql statement. Because the result of this one is incoherent.
Also, remember this is not 'code revision service'. Please, read how to create a Minimal, Complete, and Verifiable example in order your question also help other users.

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'

Something wrong with my mySQL query

SELECT t.id, t.active, t.off, t.duration, t.user
FROM table t
WHERE t.active = '0000-00-00 00:00:00'
OR t.duration != '0'
AND t.user = '1'
AND t.off = '0000-00-00 00:00:00'
LIMIT 0 , 30
Basically it's ignoring the t.off part, whats wrong?
Thank you =)
(the query was edited for an example purpose, the real query is similar to this but with other table names, etc)
== [ Update ] ==
SELECT t.active, t.off, t.duration, t.user
FROM table t
WHERE (
t.active = '0000-00-00 00:00:00'
OR t.duration != '0'
)
AND t.user = '1'
AND t.off = '0000-00-00 00:00:00'
LIMIT 0 , 30
UNION ALL
SELECT c.active, c.off, c.duration, c.user
FROM chair c
WHERE (
c.active = '0000-00-00 00:00:00'
OR c.duration != '0'
)
AND c.user = '1'
AND c.off = '0000-00-00 00:00:00'
You should use parenthesis, to group conditions (and / or), to make sure they are evaluated in the order you want.
For example, do you want to following :
SELECT t.id, t.active, t.off, t.duration, t.user
FROM table t
WHERE t.active = '0000-00-00 00:00:00'
OR (
t.duration != '0'
AND t.user = '1'
AND t.off = '0000-00-00 00:00:00'
)
LIMIT 0 , 30
Or the following :
SELECT t.id, t.active, t.off, t.duration, t.user
FROM table t
WHERE (
t.active = '0000-00-00 00:00:00'
OR t.duration != '0'
)
AND t.user = '1'
AND t.off = '0000-00-00 00:00:00'
LIMIT 0 , 30
Or maybe something else ?
Using parenthesis will make your query easier to read -- and will help making sure the conditions are evaluated properly.