I have this particular salect query which acts strange:
(1)
select date_add(
CURRENT_DATE(),
INTERVAL 7*0+(CASE
WHEN tutoring_disponibilities.day < weekday(CURRENT_DATE())
THEN 7+(tutoring_disponibilities.day-weekday(CURRENT_DATE()))
ELSE tutoring_disponibilities.day-weekday(CURRENT_DATE())
END
)
DAY
) from tutoring_disponibilities where date_add(
CURRENT_DATE(),
INTERVAL 7*0+(CASE
WHEN tutoring_disponibilities.day < weekday(CURRENT_DATE())
THEN 7+(tutoring_disponibilities.day-weekday(CURRENT_DATE()))
ELSE tutoring_disponibilities.day-weekday(CURRENT_DATE())
END
)
DAY
) NOT IN (SELECT date(tutoring_sessions.startDate) from tutoring_sessions);
This returns nothing, but this (which is the first part of the where):
(2)
select date_add(
CURRENT_DATE(),
INTERVAL 7*0+(CASE
WHEN tutoring_disponibilities.day < weekday(CURRENT_DATE())
THEN 7+(tutoring_disponibilities.day-weekday(CURRENT_DATE()))
ELSE tutoring_disponibilities.day-weekday(CURRENT_DATE())
END
)
DAY
)
from tutoring_disponibilities;
returns:
'2020-03-30'
'2020-03-30'
'2020-03-31'
'2020-03-31'
'2020-03-25'
'2020-03-25'
and this part:
(3)
SELECT date(tutoring_sessions.startDate) from tutoring_sessions;
returns this:
'2020-01-29'
NULL
NULL
NULL
'2020-02-05'
'2020-02-05'
'2020-02-10'
'2020-02-11'
'2020-02-18'
'2020-02-17'
'2020-02-25'
'2020-02-24'
'2020-03-02'
'2020-03-09'
'2020-03-16'
'2020-03-23'
'2020-02-13'
'2020-02-13'
'2020-02-13'
'2020-02-24'
'2020-02-29'
'2020-03-14'
'2020-03-30'
'2020-03-30'
'2020-03-30'
We can see that '2020-03-30'is in the results of query (3) and also in the results of query (2), but the other results of query (2) are not present in the results of query (3).
So why query(1) doesn't return anything?
If you know a better way to express this code I would be glad of any kind of help!
My recommendation is not to use NOT IN with subqueries. The reason is that any NULL value in the subquery causes no rows to be returned.
I recommend NOT EXISTS. However, your expression is rather complicated, so the simplest fix to your query is:
NOT IN (SELECT date(tutoring_sessions.startDate)
FROM tutoring_sessions
WHERE tutoring_sessions.startDate IS NOT NULL
)
With an index on tutoring_sessions(startDate), the equivalent NOT EXISTS may also be noticeably faster.
Related
i have a timestamp column in my DB and i want to sum the number of rows that are passed due, let me show you the query for that!
SELECT TIMESTAMPDIFF(MINUTE, `Opened`, NOW()) as PastDue FROM `Task`
not this query returns the perfect result and return all rows where past due is negative and others are positive
now i want to count the number of negative rows so i did
SELECT COUNT(TIMESTAMPDIFF(MINUTE, `Opened`, NOW())) < 0 as PastDue FROM `Task`
it currently returns 0 now there are two rows with negative result so it should return two but it always returns 0 , can anyone point out what i am missing?
COUNT(TIMESTAMPDIFF(MINUTE, `Opened`, NOW())) < 0
is a boolean expression (checking whether the COUNT is less than 0), which will always return 0 (false) since a COUNT must be at least 0. What you can do instead is SUM the results of the test (since MySQL treats booleans as 0 or 1 in a numeric context):
SELECT SUM(TIMESTAMPDIFF(MINUTE, `Opened`, NOW()) < 0) as PastDue FROM `Task`
Note that you can simplify this query to just compare Opened with NOW(), either in the SUM:
SELECT SUM(`Opened` > NOW()) AS PastDue
FROM `Task`
or using COUNT(*) with a WHERE clause:
SELECT COUNT(*) AS PastDue
FROM `Task`
WHERE `Opened` > NOW()
Note that based on the wording of your question, you probably want to change the condition from
`Opened` > NOW()
to
`Opened` < NOW()
i am running my query
SELECT
DATE_FORMAT(FROM_DAYS(TO_DAYS(st_day_request) -MOD(TO_DAYS(st_day_request) -2, 7)), '%d-%m-%Y') as DATE,
tx_report_id AS 'BUSINESS',
CONCAT(ROUND(AVG(DATEDIFF(dt_dossier_sent,st_day_request) > -5 AND (main.dt_dossier_sent IS NOT NULL AND main.dt_dossier_sent <> '0000-00-00')) * 100),'%') as DISPATCHED_5_AND_MORE,
CONCAT(ROUND(AVG(DATEDIFF(dt_dossier_sent,st_day_request) < -5 AND DATEDIFF(dt_dossier_sent,st_day_request) <= 1 AND (main.dt_dossier_sent IS NOT NULL AND main.dt_dossier_sent <> '0000-00-00')) * 100),'%') as DISPATCHED_4_TO_1,
CONCAT(ROUND(AVG(DATEDIFF(dt_dossier_sent,st_day_request) > 1 AND DATEDIFF(dt_dossier_sent,st_day_request) <= 10 AND (main.dt_dossier_sent IS NOT NULL AND main.dt_dossier_sent <> '0000-00-00')) * 100),'%') as DISPATCHED_2_TO_10,
CONCAT(ROUND(AVG(DATEDIFF(dt_dossier_sent,st_day_request) > 10 AND (main.dt_dossier_sent IS NOT NULL AND main.dt_dossier_sent <> '0000-00-00')) * 100),'%') as DISPATCHED_10_AND_MORE,
CONCAT(ROUND(AVG(main.dt_dossier_sent IS NULL OR main.dt_dossier_sent = '0000-00-00') * 100),'%') as OUTSTANDING FROM
(
SELECT
app_contract.id_app,
app_contract.dt_dossier_sent,
contract.tx_report_id,
contract.st_day_request
FROM
contract
INNER JOIN app_contract ON app_contract.id_contract = contract.id_contract AND contract.st_day_request > '2017-09-01' AND contract.id_client = 657
INNER JOIN app_hist ON app_hist.id_app=app_contract.id_app
GROUP BY app_contract.id_app
) as main GROUP BY DATE ORDER BY DATE_FORMAT(st_day_request, '%y') ASC, DATE_FORMAT(st_day_request, '%m') ASC
and getting the results on the image below:
Up to here, everything is correct. The Problem i have is that i want to change (pivot/crosstab) my results and put the dates i get as Columns, as you can see in the next image below:
I am trying for a couple of days but unfortunately without result. Any ideas?
PS. If you cannot see the images properly, please right click and open in new tab. Then you can enlarge them. Sorry for the images, i will copy-and paste the results in my next post.
Follow the tags -- there are many examples of how to do it in MySQL. Also, here is an automated way to generate SQL from a MySQL Stored Procedure: http://mysql.rjweb.org/doc.php/pivot
(Personally, I use generic PHP code that turns a 3-column table into a matrix.)
I have this query:
$sqlquery="SELECT * FROM tableusers WHERE status = 'off' IN (SELECT DATE(mydate) AS mydate FROM tableusers where mydate < CURDATE()) ";
This return:
off
off
on
This should return pure off:
off
off
off
How can I just return user status according to old day with condition less that today?
Sorry but I didn't get your question clearly, and I don't have enough reputation for comment. Below is one solution which you can try:
SELECT * FROM tableusers WHERE status = 'off' AND mydate < CURDATE()
This will return all the rows, where status is off and mydate is less than CURDATE() that is today.
Please elaborate your question so that we can understand it clearly. What is the purpose of your query? What output are you expecting?
This is your query:
SELECT *
FROM tableusers
WHERE status = 'off' IN (SELECT DATE(mydate) AS mydate
FROM tableusers
WHERE mydate < CURDATE()
);
Do you see anything wrong with it? Most databases would fail with a syntax error somewhere near the IN.
It is a very unusual construct, so I'm not sure if it is parsed as:
WHERE (status = 'off') IN (SELECT DATE(mydate) FROM tableusers WHERE mydate < CURDATE());
or:
WHERE status = ( 'off' IN (SELECT DATE(mydate) FROM tableusers WHERE mydate < CURDATE()) )
I am guessing the latter (based on the fact that some rows are returned). The "off IN" portions returns a boolean, which gets treated as 0. Both 'on' and 'off' would be converted to numbers for the comparison -- and hence 0 = 0 and either value matches.
I would suggest that you compare dates to dates. I don't, however, know the logic that you really intend.
I'm new in MySql, what I want is get date from database and then get different from date now, maybe something like this:
SELECT DATEDIFF(SELECT `pro_masastr` FROM `i2n_profiler_users` WHERE `userid` = 725, NOW()) AS DiffDate
but these query return error message.
Is this what you are looking for?
SELECT DATEDIFF(`pro_masastr`, NOW()) as DiffDate
FROM `i2n_profiler_users`
WHERE `userid` = 725;
This is no need for the additional subquery. Note thate datediff() is expr1 - expr2, so you might want the arguments in the other order:
SELECT DATEDIFF(now(), `pro_masastr`) as DiffDate
FROM `i2n_profiler_users`
WHERE `userid` = 725;
SELECT DATEDIFF(NOW(), 'pro_masastr') as DiffDate
FROM i2n_profiler_users
WHERE userid = SOME_ID_HERE;
I need to return two different results in a single query. When I run them independently, the first returns no rows (that's fine) and the second returns some rows (also fine). When I UNION ALL them, I get 1048 - Column "Date" cannot be null.
I need resulting rows of Date, PW, errors which I will feed a graph to show me what's going on in the system at the points in time specified by Date. In both tables, Date is of the format DateTime and must never be NULL.
SELECT `Date`, COUNT(`ID`) AS `PW`, 0 AS `errors`
FROM `systemlogins`
WHERE `Result` = 'PasswordFailure' AND `Date` >= DATE_SUB(NOW(), INTERVAL 1 DAY)
UNION ALL
SELECT `Date`, 0 AS `PW`, COUNT(`ID`) AS `errors`
FROM `systemerrors`
WHERE `Date` >= DATE_SUB(NOW(), INTERVAL 1 DAY)
GROUP BY ( 4 * HOUR( `Date` ) + FLOOR( MINUTE( `Date` )/15)) --i.e. full 1/4s of hour
ORDER BY ( 4 * HOUR( `Date` ) + FLOOR( MINUTE( `Date` )/15))
I have read that MySQL might ignore tables' NOT NULL conditions in UNIONs, causing that error. I have indeed removed the "NOT NULL" restriction on the tables and, tada, it works. Now, those restrictions have been put there for a reason and I would like to keep them while running the aforementioned query - is there any way?
Edit:
Order is the villain - removing it returns a correct result, albeit with one empty row where Date is NULL. For my purposes, I need to order the results by Date somehow.
Why are you selecting the Date column? Since you are using a aggregate function COUNT, but there is no GROUP BY clause in any of the selects, seems to me that you do not care about the Date column.
Try adding a GROUP BY clause, or removing the Date column from the select.