在SQL中如何一直获取前一天的的数据,直到数据不为空
时间: 2024-11-27 22:15:29 浏览: 18
在SQL中,如果你想要获取某个字段(如日期)前一天的数据,并持续查询直到找到非空值,通常需要结合窗口函数 `LEAD()` 或者自连接来实现。这里是一个基本的例子,假设我们有一个名为 `sales` 的表,其中包含 `date` 和 `amount` 字段:
```sql
WITH recursive_series AS (
SELECT date, amount,
-- 如果当前日期有前一日期的数据,则lead(amount)将返回上一天的amount,否则为NULL
LEAD(amount, 1, NULL) OVER (ORDER BY date) AS previous_amount,
ROW_NUMBER() OVER (ORDER BY date) as row_num
FROM sales
)
SELECT *
FROM recursive_series
WHERE amount IS NOT NULL AND (row_num = 1 OR previous_amount IS NOT NULL)
ORDER BY date;
```
这个查询首先创建了一个递归公共表表达式(CTE),然后从最早的记录开始,逐行检查前一天的 `amount` 是否存在。如果不存在,它将继续向前查找,直到找到第一个非空值或者达到第一条记录。
相关问题
在daily数据库遍历所有表格,所有表格有特殊字符,都需要加反引号 对于每个表格,查询net_mf_amount列的数据,按照trade_date降序排列 对查询结果进行pandas计算,a和b列均已存在,不需要判断,对net_mf_amount列的今天的减去前一天的数据放在a列, 将a列的值今天的减去前一天的数据放在b列,如果a和b之前计算过,则跳过计算下一个值,如果前一天数据为null则一直向前找直到有不为null的值,如果今天的值为null,则不计算,直到今天的值不为null, 保存a和b列的值 继续处理下一个表格,直到处理完所有表格
好的,我明白你的问题了。这是一个关于数据库查询和数据计算的问题,需要进行一些编程来解决。
首先,我们需要连接到数据库,并获取所有表格的名称。然后,我们使用反引号将表格名称包装起来,以便可以在包含特殊字符的表格名称上运行查询。
接下来,我们可以使用循环来遍历所有表格,并对每个表格运行查询。我们可以使用pandas来处理查询结果,并将计算后的值存储在a和b列中。
在计算过程中,我们需要检查a和b列之前是否已经计算过。我们还需要检查前一天的数据是否为null,并一直向前查找直到找到不为null的值。如果今天的值为null,则不计算,直到今天的值不为null。
最后,我们将处理后的结果保存到数据库中,并继续处理下一个表格,直到处理完所有表格。
下面是一个示例代码,可以作为参考:
```python
import pandas as pd
import pymysql
# 连接到数据库
conn = pymysql.connect(host='localhost', user='user', password='password', database='database')
# 获取所有表格的名称
cursor = conn.cursor()
cursor.execute("SHOW TABLES")
tables = cursor.fetchall()
# 遍历所有表格
for table in tables:
table_name = table[0]
table_name_quoted = '`' + table_name + '`'
# 查询net_mf_amount列的数据
query = "SELECT trade_date, net_mf_amount FROM " + table_name_quoted + " ORDER BY trade_date DESC"
df = pd.read_sql_query(query, conn)
# 计算a和b列
a_column = []
b_column = []
for i in range(len(df)):
if i == 0:
a_column.append(None)
b_column.append(None)
else:
if pd.notnull(df.iloc[i]['net_mf_amount']) and pd.notnull(df.iloc[i-1]['net_mf_amount']):
if i-2 >= 0:
if pd.notnull(df.iloc[i-2]['net_mf_amount']):
a = df.iloc[i]['net_mf_amount'] - df.iloc[i-1]['net_mf_amount']
b = df.iloc[i]['net_mf_amount'] - df.iloc[i-2]['net_mf_amount']
a_column.append(a)
b_column.append(b)
else:
j = i-3
while j >= 0:
if pd.notnull(df.iloc[j]['net_mf_amount']):
a = df.iloc[i]['net_mf_amount'] - df.iloc[i-1]['net_mf_amount']
b = df.iloc[i]['net_mf_amount'] - df.iloc[j]['net_mf_amount']
a_column.append(a)
b_column.append(b)
break
j -= 1
else:
a = df.iloc[i]['net_mf_amount'] - df.iloc[i-1]['net_mf_amount']
b = None
a_column.append(a)
b_column.append(b)
else:
a_column.append(None)
b_column.append(None)
# 将结果保存到数据库
cursor.execute("ALTER TABLE " + table_name_quoted + " ADD COLUMN a DECIMAL(10,2)")
cursor.execute("ALTER TABLE " + table_name_quoted + " ADD COLUMN b DECIMAL(10,2)")
for i in range(len(df)):
cursor.execute("UPDATE " + table_name_quoted + " SET a=%s, b=%s WHERE trade_date=%s", (a_column[i], b_column[i], df.iloc[i]['trade_date']))
conn.commit()
# 关闭连接
cursor.close()
conn.close()
```
请注意,这只是一个示例代码,具体实现可能因数据库类型和表格结构而异。因此,你需要根据实际情况进行修改和调整。
在basic数据库中读取stock_basic表格的ts_code列的数据作为表名,给表名加反引号才可以查找 在daily数据库遍历所有表格,对于每个表格 查询net_mf_amount列的数据,按照trade_date降序排列 对查询结果进行pandas计算,a和b列均已存在,不需要判断,对net_mf_amount列的前一天的数据减去今天的数据放在a列, 将a列的值前一天的数据减去今天的数据放在b列,如果a和b之前计算过,则跳过计算下一个值 保存a和b列的值 继续处理下一个表格,直到处理完所有表格,,代码报错ProgrammingError: Duplicate column name 'a'
好的,我理解了你的问题。根据你所提供的问题,我可以为你提供以下代码作为参考:
```python
import pandas as pd
import pymysql
# 建立连接
basic_conn = pymysql.connect(host='localhost', port=3306, user='root', password='123456', db='basic')
daily_conn = pymysql.connect(host='localhost', port=3306, user='root', password='123456', db='daily')
# 获取basic数据库中的表名
cursor = basic_conn.cursor()
cursor.execute("SELECT ts_code FROM stock_basic")
tables = cursor.fetchall()
# 遍历所有表格
for table in tables:
table_name = table[0]
sql = f"SELECT net_mf_amount, trade_date FROM `{table_name}` ORDER BY trade_date DESC"
cursor = daily_conn.cursor()
cursor.execute(sql)
data = cursor.fetchall()
df = pd.DataFrame(list(data), columns=['net_mf_amount', 'trade_date'])
# 对查询结果进行pandas计算
if 'a' not in df.columns and 'b' not in df.columns:
df['a'] = df['net_mf_amount'].shift(1) - df['net_mf_amount']
df['b'] = df['a'].shift(1) - df['a']
else:
continue
# 保存a和b列的值
cursor = daily_conn.cursor()
try:
cursor.execute(f"ALTER TABLE `{table_name}` ADD COLUMN a FLOAT")
cursor.execute(f"ALTER TABLE `{table_name}` ADD COLUMN b FLOAT")
except:
pass
for index, row in df.iterrows():
a_value = row['a']
b_value = row['b']
trade_date = row['trade_date']
cursor.execute(f"UPDATE `{table_name}` SET a = {a_value}, b = {b_value} WHERE trade_date = '{trade_date}'")
daily_conn.commit()
# 关闭连接
cursor.close()
basic_conn.close()
daily_conn.close()
```
这段代码会首先连接basic数据库,获取stock_basic表格中的ts_code列的数据作为表名。然后,它会连接daily数据库,并遍历所有表格,对于每个表格查询net_mf_amount列的数据,按照trade_date降序排列。接着,它会对查询结果进行pandas计算,将a和b列的值保存到数据库中,并继续处理下一个表格,直到处理完所有表格。最后,关闭连接。
需要注意的是,如果在计算过程中出现了“Duplicate column name 'a'”这个错误,可能是因为之前已经执行过保存a和b列的操作,可以在保存之前,先判断一下df中是否已经存在a和b列,如果已经存在,则跳过计算下一个值。
阅读全文