MySQL Between Statement and >= <= > < not working - mysql

i cant get my between statement to work, I can get AND EffectiveDate >= '2015-06-01' to work, as soon as i add another date condition it breaks. I have tried using CAST('2015-06-01' AS DATE) with no success, i have also tried using '2015-06-01 00:00:00' variations of dates as well with no success.
SELECT
ID,
Division,
EffectiveDate,
PM,
case Status
when 0 then 'Dead'
when 1 then 'Active'
when 2 then 'Job'
when 3 then 'Pending'
when 4 then 'Sales Lead'
when 5 then 'Budget'
when 6 then 'Change Order'
end as Status,
Name,
Address,
ProjectType,
sellPrice
FROM intranet.t_bidinfo
WHERE Division = 'TI'
AND Status = 2 OR Status = 6
AND EffectiveDate BETWEEN '2015-06-01' AND '2015-06-30'
ORDER BY EffectiveDate ASC
;

One problem with the query is that OR has lower precedence than AND: the condition on EffectiveDate does not apply to rows that have Division = 'TI'
and Status = 2.
You probably want to write
AND (Status = 2 OR Status = 6)
or, equivalently,
AND Status IN (2, 6)

Related

How do I check if a given date includes at least each of the document group listed for user?

I want to develop a SQL query to check if a given date is in at least each of document group.
The following the table
DocID UserID StartDAte EndDAte OfficialName
1 1 10/1/18 10/3/18 A
2 1 10/5/18 10/10/18 A
3 1 10/1/18 10/9/18 B
4 1 10/1/18 10/9/18 C
5 1 10/1/18 10/5/18 D
6 1 10/7/18 10/20/18 D
There are 4 document groups namely, A,B,C,D. Need to check if a given date is in atleast each of the documents in each group.
eg date : 10/2/18 is in first record of A,B,C, and first record of D. So it is passed.
eg date : 10/4/18 is not in either of documents in A hence failed.
eg date : 10/8/18 is second document in A,B,C, and second document in D hence passed.
eg date : 10/6/18 is in A but not in D hence failed.
Since I have to write this for a given user and date, I have to use "IN" clause for "OfficialName" but how could I add "OR" to check date is in any of the files in each "OfficialName" group for all documents for the given user ?
Any help is appreciated.
Need to add something not clear. Number of documents in Official name is not fixed. It could be one or many.
Aggregate and get the distinct count of groups. If you get 4, you have a match otherwise you don't.
SELECT count(DISTINCT t.officialname)
FROM elbat t
WHERE t.userid = <given user>
AND t.startdate <= <given date>
AND t.enddate >= <given date>;
You can also add a HAVING count(DISTINCT t.officialname) = 4 to get an empty set if and only if there's no match.
I think you want:
select (case when count(distinct t.officialname) = 4 then 'passed' else 'failed' end) as flag_4groups
from t
where #date <= t.startdate and
#date >= t.enddate and
t.user_id = #user;
If you want this for all users (but a given date):
select t.user_id,
(case when count(distinct t.officialname) = 4 then 'passed' else 'failed' end) as flag_4groups
from t
where #date <= t.startdate and
#date >= t.enddate
group by t.user_id
you can use this:
SELECT count(DISTINCT t.officialname)
FROM elbat t
WHERE #date between t.startDate AND t.enddate and
t.userid = #userId;

Mysql 'greater than(>)' query always returns 0

I am working with a query where I want to display number of upcoming dates. The following query returns 0 even though there are dates greater than current date. Please help me to solve this problem.
SELECT (case when b.booked_date > cast(now() as date) then sum(1) else sum(0) end) as upcoming_booked_facilities
from svk_apt_book_facilities b
where b.customer_id = 1
and b.association_id = 1
and b.is_active = 1
group by b.facility_id
You need to sum a CASE expression to do conditional aggregation:
SELECT
facility_id,
SUM(CASE WHEN booked_date > CURDATE() THEN 1 ELSE 0 END) AS upcoming_booked_facilities
FROM svk_apt_book_facilities
WHERE
customer_id = 1 AND
association_id = 1 AND
is_active = 1
GROUP BY
facility_id;
You were trying to use the sum as the predicate of the CASE expression, which is probably not what you want. Note that I am also selecting the facility_id, since you are grouping by that column. If you instead want a conditional sum over the entire table, then don't select or group by facility.

Why i get Null values in my second counter using case statement

The first case statement i got the correct result but in the second one
Why i got an NULL result Where my second case statement the counter = 2
this is the result i have an image
Query Result that i got Null data in second statement when i grouped by on my date
SELECT DISTINCT date,log,
CASE
WHEN note = 'HOLIDAY' AND counter = 1
THEN 'HOLIDAY'
END note1,
CASE
WHEN note = 'HOLIDAY' AND counter = 2
THEN 'HOLIDAY'
END note2,
FROM timesheet
WHERE timesheet.empid='40' AND date <= CURDATE() AND YEAR(date)= YEAR(CURDATE())
AND MONTH(date) = MONTH(CURDATE())
GROUP BY date
ORDER BY date DESC;
You're using GROUP BY wrong. The rule is that each column in your SELECT clause is either also in your GROUP BY clause or an aggregate function (like count, min, max, avg) must be applied to it.
When you don't follow this rule, a random row for each group is displayed. In your case, when you really have data with note = 'HOLIDAY' AND counter = 2, the rows for the group might look like this
NULL
HOLIDAY
NULL
NULL
but after collapsing (when it's outputted by the select), just the first row is displayed, therefore the NULL value.
Try it like this:
SELECT date,
MIN(log), /*or maybe you want to group by this column, too? */
MAX(CASE
WHEN note = 'HOLIDAY' AND counter = 1
THEN 'HOLIDAY'
END) note1,
MAX(CASE
WHEN note = 'HOLIDAY' AND counter = 2
THEN 'HOLIDAY'
END) note2,
FROM timesheet
WHERE timesheet.empid='40' AND date <= CURDATE() AND YEAR(date)= YEAR(CURDATE())
AND MONTH(date) = MONTH(CURDATE())
GROUP BY date
ORDER BY date DESC;
Also note, that I removed the DISTINCT. Your GROUP BY already does that.

Query returning Unexpected values

SELECT *
FROM workshop_planning_history
WHERE STATUS =1
OR STATUS =2
AND start_date =2015 -11 -29
OR end_date <=2016 -01 -10
OR end_date >=2016 -01 -10
I am running the above query and i am expecting values from Workshop_planning_history whose status is either 1 or 2 but i am getting results which have a status of 3 along with the rows having status 1 & 2.
What's wrong with my query please Help ...
You have to add some parenthesis to the predicate, because the precedence of operators is NOT AND OR, so your query is interpreted as:
SELECT *
FROM workshop_planning_history
WHERE STATUS = 1
OR (STATUS = 2 AND start_date = '2015-11-29')
OR end_date <= '2016-01-10'
OR end_date >= '2016-01-10'
Change to:
SELECT *
FROM workshop_planning_history
WHERE (STATUS = 1 OR STATUS = 2)
AND (start_date = '2015-11-29'
OR end_date <= '2016-01-10'
OR end_date >= '2016-01-10')
Or something that is proper according to your logic.
The right way to do it would be using the in clause for status.
Documentation: Here
SELECT *
FROM workshop_planning_history
WHERE STATUS in (1,2)
AND start_date =2015 -11 -29
Also why use end_date if you use both <= & >= operators?
You need to add parentesis in between AND condition of status and date comparison also its good idea to use date modifier when comparing dates
SELECT *
FROM workshop_planning_history
WHERE (STATUS =1
OR STATUS =2)
AND (date(start_date) = date '2015 -11 -29'
OR date(end_date) <=date '2016 -01 -10'
OR date(end_date) >=date '2016 -01 -10')

How to count consecutive number of 10 days

I have table with columns: id, name, date, present
Column present have values 0 or 1 or 2 and ... more
I need to count how many 0 valous is in current month 2013-07-01 - 2013-07-31 but count only when there are or more than 10 times.
for example if i have
2013-07-01 to 2013-07-10 valoues 0 it should count it and let me know that is 10 or more consecutives days like 11, 12 or more, but if it was less than 10 should count nothing.
I was trying some examples from stack... but they are different problems... so i need little help with that mysql query.
i have smth like this but need consecutives 10 days like >= 10
$sql = mysql_query("SELECT COUNT(name) as count FROM `table` WHERE (`present` = 0) AND (`date` BETWEEN '2013-07-01' AND '2013-07-31')");
while($row = mysql_fetch_array($sql)){
$result = $row['count'];
}
It counts me every 0 values in date between 2013-07-01 and 2013-07-31 but i need count how many days start from 10 or more consecutives days
column present have 0 and other numbers like 1, 2, 3... so i need count only 0 with 10 or more consecutives days
here is SqlFiddle i was trying to make warking from answer
http://sqlfiddle.com/#!2/1bde8/2
best regards
m.
This approach uses correlated subqueries to calculate two values.
The first value is the date of the previous record where Present = 1. This allows you to get the number of days in a row where Present = 0 by using datediff().
The second is the Present value of tomorrow, which will be NULL on the last day of the month. When today has Present = 0 and tomorrow is either 1 or NULL, then we can use this record. It is the end of a sequence of 0s.
From there is it just a question of adding up the values according to the conditions that you set. The following query assumes that you want to do this for each name:
select name, sum(case when datediff(date, lastPresentDate) >= 10
then datediff(date, lastPresentDate)
else 0 end) as DaysCounted
from (select t.*,
(select coalesce(max(date), '2013-06-30')
from t t2
where t2.name = t.name and
t2.present <> 0 and
t2.date <= t.date and
t2.date between '2013-07-01' and '2013-07-31'
) as lastPresentDate,
(select t2.present
from t t2
where t2.name = t.name and
t2.date = adddate(t.date, 1)
order by t2.date
limit 1
) as TomorrowPresent
from t
where date between '2013-07-01' and '2013-07-31'
) t
where Present = 0 and (TomorrowPresent = 1 and TomorrowPresent is null)
group by name
This query should give you a count only when it is 10 or greater than 10.
SELECT COUNT(`name`) as `count`
FROM `table`
WHERE (`present` = 0)
AND (`date` BETWEEN '2013-07-01' AND '2013-07-31')
HAVING `count` >= 10;
Hope it helps!
Not tested, but you could use user variables like this:-
SELECT SUM(if(ConsCounter=10, 1, 0))
FROM
(
SELECT id, name, date, present, #Counter := IF(#PrevPresent = present AND present = 0, #Counter + 1, 0) AS ConsCounter, #PrevPresent = present
FROM
(
SELECT id, name, date, present
FROM `table`
ORDER BY date
) Sub1
CROSS JOIN (SELECT #PrevPresent:=-99999, #Counter:=0) Sub2
) Sub4
Get all the records in date order and add a sequence number for the count since the present was first 0. Then count the number of times that counter is 10.