I need to make a calculation by using a mysql query.
Here is my query.
SELECT book_name,
CASE WHEN CURDATE()<book_return THEN 0 ELSE DATEDIFF(CURDATE(),book_return) END AS DateDifference,
CASE WHEN DateDifference>0 THEN DateDifference*10 ELSE NULL) END AS TotalFines FROM tblIssuedBooks order by lastupdated DESC
I need to mutiply DateDifference column by 10 if the DateDIfference value is greater than zero.but when I execute this I am getting Unknown column 'DateDifference' in 'field list' as an error.
Can someone show me how to improve this?
You can't reuse an alias in a select which was defined in the same select. One workaround here uses a subquery:
SELECT book_name, DateDifference,
CASE WHEN DateDifference > 0 THEN DateDifference*10 END AS TotalFines
FROM
(
SELECT *, CASE WHEN CURDATE() < book_return
THEN 0
ELSE DATEDIFF(CURDATE(), book_return) END AS DateDifference
FROM tblIssuedBooks
) t
ORDER BY lastupdated DESC;
Related
In MySQL Database I have a table ABC that consists of a column 'LastDate'.
LastDate which has datatype as DATETIME. The default value for this 'NULL'
I need to write a query for the table which would
Return '1' in these cases.
1) If DATEDIFF(CURRENT_TIME,LastDate) is >15 or if DATEDIFF(CURRENT_TIME,LastDate) is
NULL(i.e defaultVal).
return '0' if DATEDIFF(CURRENT_TIME,LastDate) is <15.
I tried to write an SQL query for this but was unable to do it. Please help me write this Query. Thanks in advance.
You can be explicit about your logic:
select t.*,
(case when DATEDIFF(CURRENT_TIME, LastDate) > 15 or
LastDate is null
then 1 else 0
end) as flag
from t;
This can be simplified to:
select t.*,
coalesce(DATEDIFF(CURRENT_TIME, LastDate) <= 15, 1) as flag
from t;
I have a query like this to get status without adding fields.
SELECT * ,
IF(DATEDIFF(STR_TO_DATE(end_date, "%Y-%m-%d"), CURDATE())<=0,"End","Running") status
FROM agreements
the query is running but I want to add status if the end date is less than 3 days then the status will show "will be ended"
so there will be 3 statuses in the query, END, RUNNING, Will be END
You can use CASE ..WHEN statements; also your STR_TO_DATE(end, '%Y-%m-%d') usage is unnecessary because DATEDIFF() function considers date part only for the calculation:
SELECT * ,
CASE WHEN DATEDIFF(end_date, CURDATE()) <= 0 THEN 'End'
WHEN DATEDIFF(end_date, CURDATE()) < 3 THEN 'Will Be End'
ELSE 'Running'
END status
FROM agreements
I got this table (date, indoor_km, outdoor_km,...)
I have found the SQL count to count indoor_km or outdoor_km
but I'm looking for a SQL count for the 2 columns from 1 table.
You can use the SUM function over a condition in order to count entries that satisfy your condition of IS NOT NULL:
select
sum( case when indoor_km is not null then 1 else 0 end ) As indoorKmCount,
sum( case when outdoor_km is not null then 1 else 0 end ) As outdoorKmCount
from table
You simply add them
SELECT SUM(indoor_km) + SUM(outdoor_km)
FROM...
To select the sum only for a time period simply add a WHERE clause, either using BETWEEN or >=, <=, I used the latter in my example
SELECT SUM(indoor_km) + SUM(outdoor_km)
FROM Fietsen_2018
WHERE datum >= '1/01/2018' AND datum <='31/01/2018'
Hi I was looking for a mysql query result like
As you can see there are some values have the kind of values (Ex: BV and BR or C5 and C7) how can I combine then together into one common value lets say B or C and group by that in sql?
I have the following query:
SELECT
type,
sum(case when status ='valid' then 1 else 0 end) valid_jobs,
sum(case when status ='non-valid' then 1 else 0 end) non_valid_jobs,
sum(case when status IS NULL then 1 else 0 end) null_jobs
from
main_table
where
SUBSTRING_INDEX(CAST(CAST(from_unixtime(date_generated) AS DATE) AS CHAR), '-',2) REGEXP '^2016'
group by type
Thanks in advance guys.
Otcome will look like:
Just use an expression that evaluates the value of the type column, and returns the desired result.
What's not clear from the question is the "mapping" from type to the value you want returned in the first column. It looks like we might be looking at just the first character of value in the type column.
SUBSTR(type,1,1)
If the "mapping" is more involved, then we could use a CASE expression. For example:
CASE
WHEN type IN ('BV','BR','BT','ZB') THEN 'B'
WHEN type IN ('C5','C7') THEN 'C'
WHEN ... THEN ...
ELSE type
END
We'd use that as the first expression in the SELECT list (replacing the reference to the type column in the original query), and in the GROUP BY clause.
On an (unrelated) performance note, we'd prefer conditions in the WHERE clause to be on bare columns. That allows MySQL to make use of an (efficient) range scan operation on an appropriate index.
With this condition:
WHERE SUBSTRING_INDEX(CAST(CAST(FROM_UNIXTIME( t.date_generated ) AS DATE) AS CHAR), '-',2)
REGEXP '^2016'
We're forcing MySQL to evaluate the expression on the left side for every row in the table. And the value returned by the expression is compared.
If what we're really trying to do is get date_generated values in 2016, assuming that date_generated is INTEGER type, storing 32-bit unix-style number of seconds since beginning of the era 1970-01-01...
We can do something like this:
WHERE t.date_generated >= UNIX_TIMESTAMP('2016-01-01')
AND t.date_generated < UNIX_TIMESTAMP('2017-01-01')
MySQL will see that as a range operation on the values in te date_generated column. And with that, MySQL can make effective use of an index that has date_generated as a leading column.
Just replace expr with the expression that returns the values you want in the first column:
SELECT expr
, SUM(IF( t.status = 'valid' ,1,0)) AS valid_jobs
, SUM(IF( t.status = 'non-valid' ,1,0)) AS non_valid_jobs
, SUM(IF( t.status IS NULL ,1,0)) AS null_jobs
FROM main_table t
WHERE t.date_generated >= UNIX_TIMESTAMP('2016-01-01')
AND t.date_generated < UNIX_TIMESTAMP('2017-01-01')
GROUP BY expr
EDIT
To guarantee that rows are returned in a particular sequence, add an ORDER BY clause, e.g.
ORDER BY 1
try this,
SELECT
LEFT(type,1) AS type,
sum(case when status ='valid' then 1 else 0 end) valid_jobs,
sum(case when status ='non-valid' then 1 else 0 end) non_valid_jobs,
sum(case when status IS NULL then 1 else 0 end) null_jobs
FROM
main_table
WHERE
SUBSTRING_INDEX(CAST(CAST(from_unixtime(date_generated) AS DATE) AS CHAR), '-',2) REGEXP '^2016'
GROUP BY
type
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.