MySQL:自动执行这个查询链(从值中创建新列)

2024-04-25 04:47:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含如下数据的表:

date          met       val

2012-10-18    avgt    63.3617
2012-10-16    avgt    65.7312
2012-10-19    avgt    66.4952
2012-10-17    avgt    67.3747
2012-10-18    cdd     53.3617
2012-10-17    cdd     55.3472
2012-10-19    cdd     66.8063
2012-10-16    cdd     67.3116
2012-10-18    maxt    43.3617
2012-10-19    maxt    47.4484
2012-10-16    maxt    65.9559
2012-10-17    maxt    66.2868
2012-10-19    mint    56.0447
2012-10-16    mint    65.0656
2012-10-18    mint    65.0656
2012-10-17    mint    66.4952

met列只有4个可能的值(avgt、mint、maxt、cdd、hdd),它们标记了val列中的数据。我需要一个查询(可能是一个存储过程),它将重新排列数据,使其看起来像这样:

 date           avgt        cdd         maxt        mint
 2012-10-16     65.7312     67.3116     65.9559     65.0656 
 2012-10-17     67.3747     55.3472     66.2868     66.4952 
 2012-10-18     63.3617     53.3617     43.3617     65.0656 
 2012-10-19     56.0447     66.8063     47.4484     56.0447 

以静态的方式做这件事很容易。但是我希望这是动态的,这样,不管met列中的值实际上是什么,都可以正确地重新排列。你知道吗

下面是如何手动执行此操作:

添加其他列:
ALTER TABLE MYTABLE  
ADD COLUMN  avgt FLOAT( 15, 5 ) NOT NULL AFTER  val , 
ADD COLUMN  mint FLOAT( 15, 5 ) NOT NULL AFTER  avgt , 
ADD COLUMN  maxt FLOAT( 15, 5 ) NOT NULL AFTER  mint , 
ADD COLUMN  cdd  FLOAT( 15, 5 ) NOT NULL AFTER  hdd
更新每行的新列:
UPDATE MYTABLE
SET avgt = val WHERE metric == 'avgt';
SET mint = val WHERE metric == 'mint';
SET maxt = val WHERE metric == 'maxt';
SET cdd  = val WHERE metric == 'cdd';
删除旧列
ALTER TABLE MYTABLE
DROP COLUMN met,
DROP COLUMN val;
我也了解如何获得唯一met值的列表:
SELECT DISTINCT met FROM MYTABLE

我在两者之间缺乏的逻辑。我需要遍历不同的值。如果有人能帮我,我将不胜感激。你知道吗

我将接受用纯SQL(可能是存储过程)或Python编写的答案。你知道吗

非常感谢!你知道吗


Tags: addmytablenotcolumnvalfloatwherenull
1条回答
网友
1楼 · 发布于 2024-04-25 04:47:11

因为您需要一个灵活的解决方案,它不依赖于met列中的值,所以最好的方法是在从数据库获取数据之后用python来实现

data_str = """2012-10-18    avgt    63.3617
2012-10-16    avgt    65.7312
2012-10-19    avgt    66.4952
2012-10-17    avgt    67.3747
2012-10-18    cdd     53.3617
2012-10-17    cdd     55.3472
2012-10-19    cdd     66.8063
2012-10-16    cdd     67.3116
2012-10-18    maxt    43.3617
2012-10-19    maxt    47.4484
2012-10-16    maxt    65.9559
2012-10-17    maxt    66.2868
2012-10-19    mint    56.0447
2012-10-16    mint    65.0656
2012-10-18    mint    65.0656
2012-10-17    mint    66.4952"""

data = []
# convert to array data as it would be from sql
for line in data_str.split("\n"):
    row = line.split()
    data.append(row)

# ######## this is the code required to process sql output
import collections
date_map = collections.defaultdict(dict)
for date, met, val in data:
    date_map[date][met] = val

rows = []
for date, data in date_map.iteritems():
    row = [date]
    rows.append(row)
    values = data.items()
    values.sort()
    row.extend((v for met, v in values))
    print row

输出:

['2012-10-19', '66.4952', '66.8063', '47.4484', '56.0447']
['2012-10-18', '63.3617', '53.3617', '43.3617', '65.0656']
['2012-10-17', '67.3747', '55.3472', '66.2868', '66.4952']
['2012-10-16', '65.7312', '67.3116', '65.9559', '65.0656']

相关问题 更多 >