python - MySQL/SQL 根据条件查询结果后设置的参数进行查询 - 该函数之前在 Python 中编写,读取 CSV 文件

标签 python mysql sql csv subquery

我有一个包含此数据的表:

"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"

这是表格的视觉布局: enter image description here

此表包含温室设置的参数。传递当前日期和时间,我需要获取传递的日期在 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/

相关文章:

python - 为特定范围内的值建立索引

python - 运行 makemigrations django 后出现 mysql 格式错误的数据包错误

java - Hibernate/mysql连接池

mysql - SQL - Where...In 子句中的选择联合

SQL 阶梯查询

python - 如何用不在括号内的逗号分隔?

python - 根据错误显示定制的异常消息

mysql - Wordpress:从特定类别的帖子生成标签数组

mysql - 查找年月在指定年月对之间的记录

php - 当我尝试从 RedBeanPHP 中通过 R::exec 执行查询时,为什么会出现错误?