如何在MySQL中将IFNULL与窗口函数一起使用

时间:2018-07-15 19:59:53

标签: mysql sql null window-functions ifnull

如何将ifnull与窗口函数一起使用?

比方说我在下面有这个查询结果,lag1只是使用window函数向下移动的预算列,因此,该值为null。但是我想用零替换该null,以便我可以计算预算和lag1之间的差。

select id, budget,
    lag(budget) over (order by id) as lag1
    from projects;

+----+---------+---------+
| id | budget  | lag1    |
+----+---------+---------+    
|  1 | 1000000 |    NULL |  
|  2 |  100000 | 1000000 |  
|  3 |     100 |  100000 |
+----+---------+---------+

我尝试了以下两个示例,但不起作用:

select id, budget,
ifnull(lag(budget),0) over (order by id) as lag1
from projects;

select id, budget,
ifnull((lag(budget) over (order by id) as lag1),0)
from projects;

2 个答案:

答案 0 :(得分:1)

lag()最多接受三个参数。第一个是返回值的表达式。这只是列名。第二个参数决定了它应该落后多少行。默认值为1。第三,对您来说有趣的是,如果未找到上一行,则为默认值。

因此,您可以直接在lag()调用中定义默认值:

SELECT id,
       budget,
       lag(budget, 1, 0) OVER (ORDER BY id) lag1
       FROM projects;

答案 1 :(得分:0)

我猜您的import React, { Component } from 'react'; import { Row, Col } from 'antd'; import PageHeader from '../../components/utility/pageHeader'; import Box from '../../components/utility/box'; import LayoutWrapper from '../../components/utility/layoutWrapper.js'; import ContentHolder from '../../components/utility/contentHolder'; import basicStyle from '../../settings/basicStyle'; import IntlMessages from '../../components/utility/intlMessages'; import { adalApiFetch } from '../../adalConfig'; const data = { TenantId: this.state.tenantid, TenanrUrl: this.state.tenanturl, TenantPassword: this.state.tenantpassword }; const options = { method: 'post', data: data, config: { headers: { 'Content-Type': 'multipart/form-data' } } }; export default class extends Component { constructor(props) { super(props); this.state = {TenantId: '',TenanrUrl:'',TenantPassword:''}; this.handleChangeTenantUrl = this.handleChangeTenantUrl.bind(this); this.handleChangeTenantPassword = this.handleChangeTenantPassword.bind(this); this.handleChangeTenantId= this.handleChangeTenantId.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChangeTenantUrl(event){ this.setState({tenanturl: event.target.value}); } handleChangeTenantPassword(event){ this.setState({tenantpassword: event.target.value}); } handleChangeTenantId(event){ this.setState({tenantid: event.target.value}); } handleSubmit(event){ alert('A name was submitted: ' + this.state.value); event.preventDefault(); this.data.append("TenantId", this.state.tenantid); this.data.append("TenanrUrl", this.state.tenanturl); this.data.append("TenantPassword", this.state.tenantpassword); const options = { method: 'post', data: this.data, config: { headers: { 'Content-Type': 'multipart/form-data' } } }; adalApiFetch(options) .then(response => response.json()) .then(responseJson => { if (!this.isCancelled) { this.setState({ data: responseJson }); } }) .catch(error => { console.error(error); }); } upload(e){ let data = new FormData(); //Append files to form data let files = e.target.files; for (let i = 0; i < files.length; i++) { data.append('files', files[i], files[i].name); } } render(){ const { data } = this.state; const { rowStyle, colStyle, gutter } = basicStyle; return ( <div> <LayoutWrapper> <PageHeader>{<IntlMessages id="pageTitles.TenantAdministration" />}</PageHeader> <Row style={rowStyle} gutter={gutter} justify="start"> <Col md={12} sm={12} xs={24} style={colStyle}> <Box title={<IntlMessages id="pageTitles.TenantAdministration" />} subtitle={<IntlMessages id="pageTitles.TenantAdministration" />} > <ContentHolder> <form onSubmit={this.handleSubmit}> <label> TenantId: <input type="text" value={this.state.tenantid} onChange={this.handleChangeTenantId} /> </label> <label> TenantUrl: <input type="text" value={this.state.tenanturl} onChange={this.handleChangeTenantUrl} /> </label> <label> TenantPassword: <input type="text" value={this.state.tenantpassword} onChange={this.handleChangeTenantPassword} /> </label> <label> Certificate: <input onChange = { e => this.upload(e) } type = "file" id = "files" ref = { file => this.fileUpload } /> </label> <input type="submit" value="Submit" /> </form> </ContentHolder> </Box> </Col> </Row> </LayoutWrapper> </div> ); } } 版本低于8.0,因为您的第二个解决方案已经完成。

mysql

sqlfiddle

如果您的select id, budget, ifnull(lag(budget) over (order by id),0) as lag1 from projects; 版本低于8.0,则需要在mysql中编写一个子查询,以在select前获得行数据

TESTDDL

ID

查询

CREATE TABLE projects(
  ID INT,
   budget INT
);
INSERT INTO projects VALUES (1,1000000);
INSERT INTO projects VALUES (2,100000);
INSERT INTO projects VALUES (3,100);

[结果]

SELECT *,IFNULL((select budget FROM projects t1 WHERE t.id > t1.id order by t1.id desc limit 1 ) ,0) lag1
FROM projects t

sqlfiddle