带有多个子查询的sql查询

时间:2016-08-03 13:31:37

标签: php sql-server database

我正在尝试执行一个sql查询,它将帮助我实现以下结果:

----------------------------------------------------------------------------
| RowNum |      email      |    point_1    |    point_2    |  total_point  |
----------------------------------------------------------------------------
|   1    |  abc@gmail.com  |      120      |      70       |      190      |
----------------------------------------------------------------------------

Sql查询语句1(获取RowNum,email和point_1的值):

    $sql = "
            select * 
            from 
            (
                 select ROW_NUMBER() OVER (ORDER BY m.first_name) as **RowNum**,
                 ltrim(rtrim(m.email_addr)) AS **email**,
                 CAST(isnull(p.points_accumulated,'0') AS INT) AS **point_1**

                 FROM (select * from crm_member_list where coy_id='HSG' and mbr_id not in (select mbr_id from o2o_tmp_mbr_issues_exclude) ) m
                    left join (select * from crm_member_points where coy_id='HSG') p
                    on p.mbr_id = m.mbr_id
                    where m.email_addr = 'abc@gmail.com'

                    and m.date BETWEEN '2016-08-01 00:00:00' AND '2016-08-31 23:59:00'
                )sub where RowNum>? and RowNum<?  order by RowNum";

Sql查询语句2(获取point_2的值):

    $sql = "
            select CAST(isnull(p.points_accumulated,'0') AS INT) AS **point_2** 
                    FROM (select * from crm_member_list where coy_id='HSG' and mbr_id not in (select mbr_id from o2o_tmp_mbr_issues_exclude) ) m
                            left join (select * from crm_member_points where coy_id='HSG') p
                            on p.mbr_id = m.mbr_id
                            where m.email_addr = 'abc@gmail.com'
                            and m.date BETWEEN '2016-09-01 00:00:00' AND '2016-09-30 23:59:00'";

我尝试将上面显示的2个语句组合起来得到结果,但是我得到了错误

  

“直接执行sql,没有游标”。

合并代码:

$sql = "
                select * 
                from 
                (
                     (select ROW_NUMBER() OVER (ORDER BY m.first_name) as **RowNum**,
                     ltrim(rtrim(m.email_addr)) AS **email**,
                     CAST(isnull(p.points_accumulated,'0') AS INT) AS **point_1**

                     FROM (select * from crm_member_list where coy_id='HSG' and mbr_id not in (select mbr_id from o2o_tmp_mbr_issues_exclude) ) m
                        left join (select * from crm_member_points where coy_id='HSG') p
                        on p.mbr_id = m.mbr_id
                        where m.email_addr = 'abc@gmail.com'
                        and m.date BETWEEN '2016-08-01 00:00:00' AND '2016-08-31 23:59:00'), 





                    (select CAST(isnull(p.points_accumulated,'0') AS INT) AS **point_2** 
                    FROM (select * from crm_member_list where coy_id='HSG' and mbr_id not in (select mbr_id from o2o_tmp_mbr_issues_exclude) ) m
                            left join (select * from crm_member_points where coy_id='HSG') p
                            on p.mbr_id = m.mbr_id
                            where m.email_addr = 'abc@gmail.com'
                            and m.date BETWEEN '2016-09-01 00:00:00' AND '2016-09-30 23:59:00'
                    )
               )sub where RowNum>? and RowNum<?  order by RowNum";

我应该如何组合两个查询语句来生成上面显示的结果?如何添加point_1和point_2的列以获取total_point列?

提前致谢

1 个答案:

答案 0 :(得分:0)

如果我正确理解您的问题(假设您没有使用mysql,因为它不支持row_number),一种方法是使用{ {1}}。我还认为你实际上每个月要点conditional aggregation而不是每个月选1:

sum

请注意我已将select *, row_number() over (order by first_name) rn from ( select m.first_name, ltrim(rtrim(m.email_addr)) AS email, sum(case when m.date >= '2016-08-01' AND m.Date < '2016-09-01' then CAST(isnull(p.points_accumulated,'0') AS INT) end ) as point_1, sum(case when m.date >= '2016-09-01' AND m.Date < '2016-10-01' then CAST(isnull(p.points_accumulated,'0') AS INT) end ) as point_2, sum(CAST(isnull(p.points_accumulated,'0') AS INT)) from crm_member_list m left join crm_member_points p on m.coy_id = p.coy_id and p.mbr_id = m.mbr_id where m.coy_id = 'HSG' and m.mbr_id not in (select mbr_id from o2o_tmp_mbr_issues_exclude) and m.date >= '2016-08-01' AND m.date < '2016-10-01' group by 1, 2 ) t 声明更改为使用between<。用这种方法解决问题的机会较少。