counting rows that date hasn't yet passed - sql

I am trying to count the number of rows whose date has not yet passed so i can get only the current records
I get an error sayng
MySQL error #111 Invalid use of group function
SELECT COUNT(festivalid) FROM festivals WHERE min(datefrom) > now()

SELECT COUNT(festivalid)
FROM festivals
WHERE datefrom > now()
Don't use the min function. That selects the minimum date which is not what you are looking for.
The min function is normally used as follows
SELECT MIN(dateFrom) FROM festivals

don't use MIN...
SELECT COUNT(festivalid) FROM festivals WHERE datefrom > now()

The reason for the error is that you can not use aggregate (IE: MIN, MAX, COUNT...) functions in the WHERE clause - only in the HAVING clause can you do this. And to define the HAVING clause, your query needs to have a GROUP BY clause defined:
SELECT COUNT(f.festivalid)
FROM FESTIVALS f
GROUP BY ? --festivalid would NOT be an ideal choice
HAVING MIN(datefrom) > now()
...but I have my doubts about the query, and think it would be better to use:
SELECT COUNT(f.festivalid)
FROM FESTIVALS f
WHERE f.datefrom > CURRENT_TIMESTAMP
CURRENT_TIMESTAMP is ANSI standard equivalent to MySQL specific NOW(), making the query portable to other databases.

Related

distict cant use in this

I want to display my data without duplication in any of the columns,
I use distinct or group by tetep it doesn't work
my sql :
SELECT DISTINCT rl.NIK,date(rl.enroll),LEFT(TIME(rl.enroll),8) AS time
FROM RTattandenceLog rl, mstEmp e
WHERE DATE(rl.enroll)=CURDATE()-1 AND e.idDept=3 AND e.NIK=rl.NIK
this is resultc:
the lines I crossed should not be displayed
Basically, you want an aggregation query with JOIN. I'm not sure why you are separating out the date/time into two columns instead of just using:
SELECT rl.NIK, DATE(rl.enroll),
CAST(MIN(TIME(rl.enroll)) as CHAR)
FROM RTattandenceLog rl JOIN
mstEmp e
ON e.NIK = rl.NIK
WHERE rl.enroll < CURDATE() AND
rl.enroll >= CURDATE() - INTERVAL 1 DAY AND
e.idDept = 3
GROUP BY rl.NIK, DATE(rl.enroll);
Notes:
This uses proper, explicit, standard, readable JOIN syntax. Never use commas in the FROM clause.
The date comparisons do not use DATE(). That makes it this more compatible with indexes and helps the optimizer.
There is no implicit conversion of a time value into a string. Not sure why a time is not good enough (date seems to be), but this explicitly converts to a string. Implicit conversions are the cause of both semantic errors and performance problems.
I don't understand why you would want to split the date and time into separate columns. Perhaps this is sufficient:
SELECT rl.NIK, MIN(rl.enroll)
FROM RTattandenceLog rl JOIN
mstEmp e
ON e.NIK = rl.NIK
WHERE rl.enroll < CURDATE() AND
rl.enroll >= CURDATE() - INTERVAL 1 DAY AND
e.idDept = 3
GROUP BY rl.NIK, DATE(rl.enroll);
Don't you actually want to create groups here based on the NIK and the enroll date? And show the earliest time for every group?
Something like this:
SELECT rl.NIK, date(rl.enroll), LEFT(TIME(MIN(rl.enroll)), 8) AS time
FROM RTattandenceLog rl, mstEmp e
WHERE DATE(rl.enroll) = CURDATE() - 1 AND e.idDept = 3 AND e.NIK = rl.NIK
GROUP BY rl.NIK, date(rl.enroll)
I do not use MariaDB myself, so I cannot test it. But it's pretty standard SQL syntax, so I assume it should work.

Timestamp to date in SQL

Here is what I did:
Select count(check_id)
From Checks
Where timestamp::date > '2012-07-31'
Group by 1
Is it right to do it like I did or is there a better way? Should/could I have used the DateDIFF function in my WHERE clause? Something like: DATEDIFF(day, timestamp, '2012/07/31') > 0
Also, I need to figure out how I'd calculate the total rate of acceptance for this
time period? Can anyone provide their expertise with this?
Is it right to do it like I did or is there a better way?
Using a cast like that is a perfectly valid way to convert a timestamp to a date (I don't understand the reference to the non-existing datediff though - why would adding anything to a timestamp change it)
However, the cast has one drawback: if there is an index on the column "timestamp" it won't be used.
But as you just want a range after a certain date, there is no reason to cast the column to begin with.
The following will achieve the same thing as your query, but can make use of an index on the column "timestamp" in case there is one and using it is considered beneficial by the optimizer.
Select count(distinct check_id)
From Checks
Where "timestamp" > date '2012-07-31' + 1
Note the + 1 which selects the day after, otherwise the query would include rows that are on that date but after midnight.
I removed the unnecessary group by from your query.
If you want to get a count per day, then you will need to include the day in the SELECT list. In that case casting is a good way to do it:
Select "timestamp"::date, count(distinct check_id)
From Checks
Where "timestamp" > date '2012-07-31' + 1
group by "timestamp"::date

Get the following record in query

If we have a table called Activity and has rows[ActivityCode and StartTime]
for example
ActivityCode-----StartTime<BR>
Lunch------------1200<BR>
MathClass--------1300<BR>
EnglishClass-----1500<BR>
EndOfSchool------1700<BR>
And now I want to make one SQL Query to display as follow:
ActivityCode-----StartTime-----EndTime<BR>
Lunch------------1200----------1300<BR>
MathClass--------1300----------1500<BR>
EnglishClass-----1500----------1700<BR>
EndOfSchool------1700----------1700<BR>
I am not sure how to do it. I tried to follow How to get a value from previous result row of a SELECT statement?. But it didn't work as I expected. Any help is appreciated.
You can use this query:
SELECT
Activity.ActivityCode,
Activity.StartTime,
Nz((Select Top 1 StartTime
From Activity As T
Where T.StartTime > Activity.StartTime
Order By StartTime Asc),
[StartTime]) AS EndTime,
CDate(TimeSerial(Val([EndTime])\100,Val([EndTime]) Mod 100,0)-
TimeSerial(Val([StartTime])\100,Val([StartTime]) Mod 100,0)) AS Duration
FROM
Activity;
Output:
I would use a subquery with aggregation:
select a.*,
(select nz(min(a2.starttime), a.endtime)
from activity as a2
where a2.starttime > a.starttime
) as endtime
from activity as a;
Normally in such an example, there would be an additional column identifying a "grouping" of some sort -- such as a person. If you have such a column, you would have an equality condition in the subquery as well as the inequality on time.
Also, there are much better ways to do this in almost any other database -- notably, the lead() function.

SQL - All appointments to current day

I have following query and I get followig error:
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS
I want that dodate is less than date today so if i have appointments which isn't marked as "done" so query will list all of my appointments to current day.
select
dodate, regdate,header,starttime,stoptime,userid,custid,objid,infoid,aname
from fkms.appointment
where
done=0 and del=0
and dodate > (SELECT dodate,
DATEADD(d,dodate - 2440587,'1970-01-01'),
ts,
DATEADD(s,ts,'19700101 01:0:00:000')
FROM fkms.appointment)
and userid='da'
Any tips?
Your query is illegal as the inner SELECT returns more than one value. Change it to:
select
dodate, regdate,header,starttime,stoptime,userid,custid,objid,infoid,aname
from fkms.appointment
where done = 0
and del = 0
and dodate > GETDATE()
and userid ='da';
NOTE: GETDATE() is SQL-SERVER function. IN Oracle you have NOW() and other DBMSs similar functions. Find out which one you need.

Aggregate on relative daterange in Oracle SQL

I have a table with several columns I would like to aggregate on, I have already aggregated on absolute days, but now I want to aggregate relatively. In my table I have a timestamp, and I would like to group by a date range so that the datestamp's day is 0, the day after 1 and so forth.
SELECT count(*) num_elements, sum(some_value) like_to_sum, reldate
FROM the_large_table
GROUP BY *** what goes here *** reldate.
Can I aggregate on the return from a function, or is there a better way to approach this problem.
If I can aggregate on the result from a function, are there any functions for this already in SQL, or how could this be solved?
SELECT
COUNT(*) AS num_elements,
SUM(some_value) AS like_to_sum,
TRUNC(SYSDATE) - TRUNC(your_date) AS rel_date
FROM the_large_table
GROUP BY TRUNC(SYSDATE) - TRUNC(your_date);