MySQL Where clause same key twice for two separate values - mysql

I am generating the following query
SELECT * FROM Report WHERE submittedOn >= :minDateFilter
AND submittedOn <= :maxDateFilter AND non_issue = 1 AND
non_issue = 0 ORDER BY submitted
However, I'm not getting anything returned (it works fine if I omit: AND non_issue = 1 AND
non_issue = 0, or omit just one of these, but nothing is being returned when both of these clauses are present.
Ideally I'd like to keep the statement how it is, as it's generated on the fly and I'd like to be able to display both types of report from the same query.
I feel like my syntax might be incorrect, but it's not throwing any errors, any suggestions?

non_issue can not have 2 values at same time on a given row. I think you would like to use OR:
SELECT * FROM Report WHERE submittedOn >= :minDateFilter
AND submittedOn <= :maxDateFilter AND (non_issue = 1 OR
non_issue = 0) ORDER BY submitted

You can use the IN instead of non_issue = 1 AND non_issue = 0 condition.
The same entry can't be non_issue equal to 0 and 1 same time.
SELECT *
FROM Report
WHERE submittedOn >= :minDateFilter AND
submittedOn <= :maxDateFilter AND
non_issue IN (0, 1)
ORDER BY submitted

Related

Is it possible to make a SQL statement, based on a single column?

I'm struggling to write down an SQL statement for a query.
Basically, I want to select a record, based on a field, if this field is bigger than 0, then it should check if 1 hour is passed from a datetime field, if the field is lower or equal to 0 then it should ignore that check and just select it
In C# it would be something like this:
if (columnA > 0)
{
//select if (columnB < DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 1 HOUR)))
//if it's not match, move on to next record
} else {
//just select it
}
So, in SQL what would be? Something like this:
SELECT field1, field2
FROM table
WHERE id = 1
AND intLv < fieldLv
AND IF (limitedLogin > 0) { lastLogin < DATE_SUB(CURRENT_TIMESTAMP, INTERVAL time HOUR) AND logins < totLogins }
ORDER BY id DESC LIMIT 1
I'm not expert on SQL/MySQL statements, so I don't know if that is entirely possible. Could someone enlighten me?
Basically, I want to select a record, based on a field, if this field is bigger than 0, then it should check if 1 hour is passed from a datetime field, if the field is lower or equal to 0 then it should ignore that check and just select it
You seem to be describing logic like this:
where columnA < 0 or
columnB < now() - interval 1 hour;
Note: This assumes that = 0 is the same as > 0.
The first condition returns all rows where columnA < 0. The second returns rows where column b is more than one hour ago.

How do I aggregate with group by in mysql withou setting sql mode?

This query gets the output I want. In order to run it I have to run
SET sql_mode = '';
Because otherwise I get an error:
SELECT list is not in GROUP BY clause and contains nonaggregated column 'knownLoss.t1.loss' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
SELECT
t1.klDate AS LDate
, t1.Category
, t1.reason AS Reason
, sum(t1.loss) AS Loss
, round(t1.loss / t2.loss,2) AS Percentage
FROM
deptkl t1
JOIN (
SELECT
Store
, sum(loss) AS loss
FROM
deptkl
WHERE
klDate >= date_sub(SUBDATE(curdate(), WEEKDAY(curdate())), interval 7 day)
AND
klDate < SUBDATE(curdate(), WEEKDAY(curdate()))
AND
Store = 19
AND
Department = 80
) t2 ON t1.Store = t2.Store
WHERE
klDate >= date_sub(SUBDATE(curdate(), WEEKDAY(curdate())), interval 7 day)
AND
klDate < SUBDATE(curdate(), WEEKDAY(curdate()))
AND
t1.Store = 19
AND
Department = 80
GROUP BY
klDate
, Category
, reason
When I place this into the Dataset and Query Dialog of Jasper Studio, I get the same error and I am unable to use the SET sql_mode = ''; command. Any thoughts? If there is a way to achieve this without using SET sql_mode = '';?
I'm guessing the error is from this line in your select:
round(t1.loss / t2.loss,2) AS Percentage
Since you GROUP BY clause does not include this column it's somewhat of a coin toss which t1.loss and t2.loss values will be used. In some cases those values happen to always be the same based on your criteria and so you get the correct results regardless, but the db will still complain since it's being asked to return somewhat arbitrary results for those columns. One way to deal with this would be to simply apply an aggregate function to the columns in question like this:
round(min(t1.loss) / min(t2.loss),2) AS Percentage
or...
round(avg(t1.loss) / avg(t2.loss),2) AS Percentage
I think you want to do this :
round(sum(t1.loss / t2.loss)/count(*),2) AS Percentage
this will calculate the sum of the average loss for every records in the result then divide it on the the count of the record of the group it's like average of average.
EDITS:
sorry i made a syntax error now ,it should give the th wanted result and the error is because you are not using aggregate function on a column that is not in group by clause

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.

How to get list of records from table where the time difference found using DATEDIFF function between 2 variables that are select queries themselves?

SET #startdate = (select LOG_TIME from log.time where sender='Japan' and receiver ='USA' and code=158);
SET #enddate = (select LOG_TIME from log.time where sender='Japan' and receiver ='USA' and code=189);
select * from log.time where DATEDIFF(minute, #startdate, #enddate) >= 10;
Here I want to use 2 variables (#startdate and #enddate) which are populated with multiple entries coming from the select queries used .
And for the last line , I want the select query to return a list of records where the DATEDIFF function is greater than or equal to 10 minutes by using these 2 variables with multiple values .
P.S I am using the Squirrel SQL Client 2.3 )
The issue is I have no idea if it is possible to use multiple values for variables.
Also please advise or provide any solution to the above issue such that the query works in the end.
You can't use variables this way.
Now it's hard to tell for sure not seeing your table schema and sample data but you should be able to do what you want using JOIN with a query like this
SELECT l1.*
FROM log.time l1 JOIN log.time l2
ON l1.sender = l2.sender
AND l1.receiver = l2.receiver
AND l1.code = 158
AND l2.code = 189
WHERE l1.sender = 'Japan'
AND l1.receiver = 'USA'
AND DATEDIFF(minute, l1.log_time, l2.log_time) >= 10
If you were to provide a table schema, sample data and desired output, then it'll be possible to test your query