Select user status and select date less today in one query - mysql

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.

Related

MariaDB SELECT query with date_add()

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.

How to use cases on order by in Mysql?

If t_date(column_name) is Today's date then
select * from `schedules`
ORDER BY available_seats <= 0 , STR_TO_DATE(departure_time,'%h:%i%p');
Else
select * from `schedules`
ORDER BY (available_seats <= 0 && (STR_TO_DATE(departure_time,'%h:%i%p') >= TIME(NOW()))), (STR_TO_DATE(departure_time,'%h:%i%p') <= TIME(NOW())), STR_TO_DATE(departure_time,'%h:%i%p');
END
Query 1 is for t_date = DATE(now())
Query 2 is for t_date != DATE(now())
How can i make it in a single query with condition on order by??
You can use CASE like below
SELECT *
FROM `schedules`
ORDER BY
available_seats <= 0 ,
CASE WHEN t_date <> CURRENT_DATE() AND (available_seats <= 0 && (STR_TO_DATE(departure_time,'%h:%i%p') >= TIME(NOW())))
THEN
(STR_TO_DATE(departure_time,'%h:%i%p') <= TIME(NOW()))
WHEN t_date = CURRENT_DATE()
THEN STR_TO_DATE(departure_time,'%h:%i%p')
ELSE STR_TO_DATE(departure_time,'%h:%i%p') END,
STR_TO_DATE(departure_time,'%h:%i%p')
In English, what are you actually trying to get your order by and maybe adjust your question for clarification...
However, I think you might want all "available_seats" values less or equal to zero FIRST, THEN based on the date from today. If that is the case, you may want something like..
order by
case when available_seats <= 0 then 1 else 2 end,
STR_TO_DATE(departure_time,'%h:%i%p')
But it should all be possible in a simple single query, but there is no context to what the seats, dates are for and what you want and why... Are you looking for something like "Sold-out" events sorted to top of list, then based on date of event with closest coming event listed first?
The case/when I have above basically puts any returned records that have available seats <= 0 in the first order sequence regardless of actual 0 or negative value... Then, anything else, if 1 seat or 1000 seats left are sorted after. The SECOND part of the order by is just on the date_time field itself. Since the order by is regardless of the "formatted" column that might be retrieved in the field list, I am just ordering by the date/based conversion as you had.

MySql: Same select count(*) query returns different results if invoked within a function or outside

Well, as simple as that. The following query returns 1:
select count(*) as Total from conversations
where TargetUserID = 2
and LastMessageSenderUserID = StarterUserID
and TotalMessages > 0
and Answered = 0
and (#ReadDate := GetConversationReadDate(ID)) is not null
and #ReadDate < date_sub(now(), interval 1 day)
I copied the very same code in the body of a stored function with one parameter user_id:
return (select count(*) as Total from conversations
where TargetUserID = user_id
and LastMessageSenderUserID = StarterUserID
and TotalMessages > 0
and Answered = 0
and (#ReadDate := GetConversationReadDate(ID)) is not null
and #ReadDate < date_sub(now(), interval 1 day))
However the latter, called with user_id = 2, returns 0. It is not deterministic and flagged as 'reads sql data'.
You are using the same variable in two parts of the where clause. This is not safe. MySQL does not guarantee the order of execution of the subclauses of a where. You should do something like:
and GetConversationReadDate(ID) < date_sub(now(), interval 1 day))
This will automatically fail if the value returned is NULL, so the NULL check is redundant.
Here is the quote from the documentation:
As a general rule, other than in SET statements, you should never
assign a value to a user variable and read the value within the same
statement.

SQL - Select all rows which is >= and <=

i trying to do a sql query which i combine de compare operators with substring.
in my column date i have the following value inside : 09-01-2014 12:02:55
what i try to now is to select all rows which is >= 09-01-2014 and for example <=22-01-2014
how can i do it?
i have trying for example with this code:
SELECT * From table Where Name= 'Something'
AND SUBSTRING(date,1,10) = '09-01-2014'
AND SUBSTRING(date,1,10) < '22-01-2014'
You can use the BETWEEN operator
SELECT * FROM table
WHERE Name = 'Something'
AND SUBSTRING(date, 1, 10) BETWEEN '09-01-2014' AND '22-01-2014'
EDIT: I'm still leaving this here, but it is not an error proof solution (as pointed out by oerkelens down in the comments)
The BETWEEN operator will work, like this:
SELECT *
From table
Where Name= 'Something'
AND `date` BETWEEN '2014-01-09' AND '2014-01-23'
Working Demo: http://sqlfiddle.com/#!2/b4d7e
Try this:
SELECT *
FROM tableA a
WHERE a.nme= 'Something' AND
DATE(STR_TO_DATE(a.date, '%d-%m-%Y %H:%i:%s')) >= '2014-01-09' AND
DATE(STR_TO_DATE(a.date, '%d-%m-%Y %H:%i:%s')) <= '2014-01-22';
OR
SELECT *
FROM tableA a
WHERE a.nme= 'Something' AND
DATE(STR_TO_DATE(a.date, '%d-%m-%Y %H:%i:%s')) BETWEEN '2014-01-09' AND '2014-01-22';
Using the following syntax makes your query sargable. It allows query to use any Indexes defined on the date column. for more information SARGable Queries with Datetime Datatype
SELECT * From table
Where Name= 'Something'
AND [DateColumn] >= '20140109'
AND [DateColumn] <= '20140122'
You are converting the date from the table row into a string before comparing to the bookend dates. You need to do the opposite. Convert the bookend dates from strings to dates, then compare each test date.
Some form of the CONVERT or CAST function should do that for you.
The reason your approach won't work is that when SQL server compares strings, it uses alphabetical order. You want ascending date order, which is a different order.
Which Database do you use? Oracle:
SELECT *
FROM table tbl
WHERE 1=1
AND name = 'Something'
AND trim(tbl.column) >= to_date('2014-01-09','DD-MM-YYYY')
AND trim(tbl.column) <= to_date('2014-01-22','DD-MM-YYYY')
or you just convert it into a number/integer like YYYYMMDD then the >= =< operators will work too.

MySQL how to convert 00-00-000 to CURDATE in query

What I want is this.
Sometimes a date field in my databse is filled with 0000-00-00 which is perfectly fine. I have no problems putting my data into my table. So I am not looking for solutions aming the alternation of my tabel from 0000-00-00 to NULL.
I want to replace/convert 0000-00-00 to CURDATE or NOW, but I haven't found any solution yet.
The query I currently use looks like this:
$sql = "(SELECT
date_format (dat_start, '%d-%m-%Y') AS dat_start,
date_format (dat_eind, '%d-%m-%Y') AS dat_eind,
o.nm,
o.acroniem,
o.orgid,
r.naam,
r.rolid,
(SELECT COUNT(*)
FROM
relatie re2
WHERE
re2.organ_orgid = relatie.organ_orgid
AND
re2.rolid_rol = relatie.rolid_rol
AND re2.dat_start
BETWEEN dat_start AND dat_eind
AND re2.dat_eind
BETWEEN dat_start AND dat_eind
) AS aantal
FROM
relatie
LEFT JOIN
organ o
ON
o.orgid = relatie.organ_orgid
LEFT JOIN
rollen r
ON
r.rolid = relatie.rolid_rol
WHERE
relatie.pers_persid = '$persid2'
ORDER BY dat_start DESC
)
How can I do that? I hope my question is clear enough. I can find lots of info about getting the data into the table but almost nothing about the situation discribed above.
Thanks in advance!
You can use IF to check if the field is '0000-00-00' or not.
DATE_FORMAT(IF(dat_start = '0000-00-00', NOW(), dat_start), '%d-%m-%Y') AS dat_start
You could use an expression like this in place of date_column (which you should replace with the name of your column):
CASE
WHEN date_column = '0000-00-00' THEN CURDATE
ELSE date_column
END
For example, in a query:
SELECT
field_a,
field_b,
CASE
WHEN date_column = '0000-00-00' THEN CURDATE
ELSE date_column
END AS adjusted_date_column
FROM a_table
WHERE ...;