我有一个包含此数据的表:
"germination_day","2019-01-02","2019-03-02","08:00:00","18:00:00","100","0","2","0","0","0","0","0","24","54","0","1300","24","120"
"germination_night","2019-01-02","2019-03-02","18:00:00","08:00:00","0","96","0","0","0","0","0","0","25","40","0","1300","24","120"
" flowering_day","2019-03-02","2019-06-02","08:00:00","06:00:00","0","0","0","0","100","0","0","10","25","40","0","1300","24","120"
"flowering_night","2019-03-02","2019-06-02","06:00:00","08:00:00","0","0","0","0","0","0","0","0","0","0","0","0","24","120"
"vegetation_day ","2019-06-02","2019-09-02","08:00:00","06:00:00","0","0","0","0","100","0","0","10","25","40","0","1300","24","120"
"vegetation_night","2019-06-02","2019-09-02","06:00:00","08:00:00","0","0","0","0","0","0","0","0","0","0","0","1300","24","120"
"maturation_day","2019-09-02","2019-12-31","08:00:00","09:00:00","0","0","0","0","0","0","0","0","0","0","0","1300","24","120"
"maturation_night","2019-09-02","2019-12-31","09:00:00","08:00:00","0","0","0","0","0","0","0","0","0","0","0","1300","24","120"
此表包含温室设置的参数。传递当前日期和时间,我需要获取传递的日期在 start_date 和 end_data 之间的范围内以及传递的当前时间在 start_hour 和 end_hour 之间的范围内的数据行。
每个阶段都是由白天和黑夜组成的。早上 8 点开始,次日早上 8 点结束。
这是我到目前为止编写的代码。它没有完成,因为我的 SQL 技能不太好。这就是我需要帮助的原因:
SET @CurrentDate = CURDATE();
SET @CurrentTime = NOW();
SELECT start_hour, end_hour,
CASE
WHEN CAST( CONCAT(@CurrentDate, ' ', end_hour) as DATETIME ) > CAST( CONCAT(@CurrentDate, ' ', '00:00:00') as DATETIME ) AND CAST( CONCAT(@CurrentDate, ' ', end_hour) as DATETIME ) <= CAST( CONCAT(@CurrentDate, ' ', '08:00:00') as DATETIME )
THEN CAST( CONCAT(@CurrentDate, ' ', end_hour) as DATETIME ) = CAST( CONCAT(@CurrentDate, ' ', end_hour) as DATETIME ) + INTERVAL 1 DAY
WHEN CAST( CONCAT(@CurrentDate, ' ', start_hour) as DATETIME ) = CAST( CONCAT(@CurrentDate, ' ', end_hour) as DATETIME )
THEN CAST( CONCAT(@CurrentDate, ' ', start_hour) as DATETIME ) - INTERVAL 1 MINUTE
WHEN NOW() >= CAST( CONCAT(@CurrentDate, ' ', start_hour) as DATETIME )
THEN "Day phase"
WHEN NOW() < CAST( CONCAT(@CurrentDate, ' ', start_hour) as DATETIME ) OR ( NOW() >= CAST( CONCAT(@CurrentDate, ' ', start_hour) as DATETIME ) AND NOW() < CAST( CONCAT(@CurrentDate, ' ', end_hour) as DATETIME ) - INTERVAL 1 DAY)
THEN "It goes to the night phase"
END AS expense_amt
FROM `RECIPE_TABLE`
WHERE CURDATE() >= start_date
AND CURDATE() < end_date
过去我在 Python 中使用 .CSV 文件。但是,现在为了获得更好的性能,我需要在 MySQL 中实现查询。
这是工作代码(可能可以改进):
def getCurRow(self):
currentTime = datetime.datetime.now().replace(microsecond=0)
inFile = open(self._recipe_file, 'rb')
reader = csv.reader(inFile, skipinitialspace=False)
headers = reader.next();
try:
for index, row in enumerate(reader):
row = [element.strip() for element in row]
if(len(row)>=0):
print("Row: "+str(row))
sDate = datetime.datetime.strptime(row[1].strip(), "%d/%m/%Y")
eDate = datetime.datetime.strptime(row[2].strip(), "%d/%m/%Y")
self.sTime = datetime.datetime.strptime(currentTime.strftime('%d/%m/%Y')+" "+row[3].strip(), "%d/%m/%Y %H:%M")
self.eTime = datetime.datetime.strptime(currentTime.strftime('%d/%m/%Y')+" "+row[4].strip(), "%d/%m/%Y %H:%M")
#sTime and eTime will be also considered for the preparation of the solution
self.sTime.replace(second=0)
self.eTime.replace(second=0)
if (eDate <= sDate):
print("Impossible eDate <= sDate ")
break
print("eTime : "+str(self.eTime)+" cond1 : "+str(currentTime.replace(hour=0,minute=0,second=0))+" "+"cond2 : "+str(currentTime.replace(hour=8,minute=0,second=0)))
if (self.eTime > currentTime.replace(hour=0,minute=0,second=0) and self.eTime <= currentTime.replace(hour=8,minute = 0,second=0)):
self.eTime = self.eTime + datetime.timedelta(days=1)
if (currentTime <= eDate and currentTime >= sDate): # check data
if (self.sTime == self.eTime):
print("sTime = eTime")
self.sTime = self.sTime - datetime.timedelta(minutes=1)
print ("currentTime: "+str(currentTime))
print ("startingDate: "+str(sDate))
print ("endDate: "+str(eDate))
print ("startingTime: "+str(self.sTime))
print ("endTime: "+str(self.eTime))
if(currentTime >=self.sTime) and (currentTime < self.eTime):
print("Day phase")
self.phaseID = index
self.phase = str(row[0].strip())
return row
break
elif (currentTime < self.sTime) or (currentTime >= self.eTime) and (currentTime < eDate - datetime.timedelta(days=1)):
#it consider the following line, the night phase
print("It goes to the night phase")
row = reader.next()
print("Night phase: "+str(row))
self.phaseID = index+1
print("phaseID: "+str(self.phaseID))
self.phase = str(row[0].strip())
self.sTime = datetime.datetime.strptime(currentTime.strftime('%d/%m/%Y')+" "+row[3].strip(), "%d/%m/%Y %H:%M")
self.eTime = datetime.datetime.strptime(currentTime.strftime('%d/%m/%Y')+" "+row[4].strip(), "%d/%m/%Y %H:%M")
self.eTime = self.eTime + datetime.timedelta(days=1)
return row
break
else:
print("Next range time")
continue
else:
print("Next range days")
continue
else:
print("There are no rows")
else:
sys.exit('Error: File configuration ended')
return None
except csv.Error as e:
sys.exit('File %s, line %d: %s' % (in_file, reader.line_num, e))
except ValueError as e:
sys.exit('Error: Configuration file not well formatted.\n%s' % e)
finally:
inFile.close()
最佳答案
很难准确理解您的需求。首先,您能否解释一下为什么以下内容还不够?
SELECT *
FROM `RECIPE_TABLE`
WHERE DATE(NOW()) BETWEEN `start_date` AND `end_date`
AND CURTIME() BETWEEN `start_hour` AND `end_hour`;
更新:
问题是时间缠绕吗?如果是这样,以下是否会产生预期的结果?
SELECT *
FROM `RECIPE_TABLE`
WHERE
(`end_hour` > `start_hour` AND CURTIME() BETWEEN `start_hour` AND `end_hour` AND DATE(NOW()) BETWEEN `start_date` AND `end_date`) OR
(`start_hour` > `end_hour` AND CURTIME() BETWEEN `start_hour` AND '00:00:00' AND DATE(NOW()) BETWEEN `start_date` AND `end_date`) OR
(`start_hour` > `end_hour` AND CURTIME() BETWEEN '00:00:00' AND `end_hour` AND DATE(NOW()) BETWEEN DATE_ADD(`start_date`, INTERVAL 1 DAY) AND DATE_ADD(`end_date`, INTERVAL 1 DAY));
更新2:
看来问题在于日期边界的定义。正如您在评论中所说,返回的两行中的第一行是您想要的,以下调整有效(我还修复了时间边界问题):
SELECT * FROM `recipe` WHERE
(`end_hour` > `start_hour` AND CURTIME() BETWEEN `start_hour` AND `end_hour` AND DATE(NOW()) > `start_date` AND DATE(NOW()) <= `end_date`) OR
(`start_hour` > `end_hour` AND CURTIME() BETWEEN `start_hour` AND '23:59:59' AND DATE(NOW()) > `start_date` AND DATE(NOW()) <= `end_date`) OR
(`start_hour` > `end_hour` AND CURTIME() BETWEEN '00:00:00' AND `end_hour` AND DATE(NOW()) > DATE_ADD(`start_date`, INTERVAL 1 DAY) AND DATE(NOW()) <= DATE_ADD(`end_date`, INTERVAL 1 DAY));
使用 SQL 中提供的数据和以下查询进行测试:
SELECT * FROM `recipe` WHERE
(`end_hour` > `start_hour` AND '09:15:00' BETWEEN `start_hour` AND `end_hour` AND '2019-09-02' > `start_date` AND '2019-09-02' <= `end_date`) OR
(`start_hour` > `end_hour` AND '09:15:00' BETWEEN `start_hour` AND '23:59:59' AND '2019-09-02' > `start_date` AND '2019-09-02' <= `end_date`) OR
(`start_hour` > `end_hour` AND '09:15:00' BETWEEN '00:00:00' AND `end_hour` AND '2019-09-02' > DATE_ADD(`start_date`, INTERVAL 1 DAY) AND '2019-09-02' <= DATE_ADD(`end_date`, INTERVAL 1 DAY));
+-----------------+------------+------------+------------+----------+---------+---------+---------+---------+---------+---------+---------+---------+-------------+----------+------------+-------------------+-----------------+-------------------+
| phase | start_date | end_date | start_hour | end_hour | color_0 | color_1 | color_2 | color_3 | color_4 | color_5 | color_6 | color_7 | temperature | humidity | photowhite | quantity_solution | quantity_cicles | quantity_duration |
+-----------------+------------+------------+------------+----------+---------+---------+---------+---------+---------+---------+---------+---------+-------------+----------+------------+-------------------+-----------------+-------------------+
| vegetation_day | 2019-06-02 | 2019-09-02 | 08:00:00 | 06:00:00 | 0 | 0 | 0 | 0 | 100 | 0 | 0 | 10 | 25 | 40 | 0 | 1300 | 24 | 120 |
+-----------------+------------+------------+------------+----------+---------+---------+---------+---------+---------+---------+---------+---------+-------------+----------+------------+-------------------+-----------------+-------------------+
1 row in set (0.02 sec)
关于python - MySQL/SQL 根据条件查询结果后设置的参数进行查询 - 该函数之前在 Python 中编写,读取 CSV 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58096482/