我可以在同一查询中选择*,COUNT(*)吗?

时间:2019-05-13 15:03:00

标签: sql oracle

我有一张访问表

ssn,eno,date
302609074,101,20180215
302609074,102,20181010
302609074,105,20190505
302609074,105,20190506
997600970,103,20190115
997600970,105,20190415
997600970,104,20181212
997600970,104,20181213
874136439,102,20190808
874136439,102,20190910
874136439,102,20191001
874136439,102,20191002

和结果表

ssn,date,scode,dcode,ppay,ipay
302609074,20180215,4002,1001,25,35
302609074,20180215,4006,1003,40,100
302609074,20181010,4002,1001,25,35
302609074,20181010,4006,1003,40,100
302609074,20190505,4002,1001,25,35
302609074,20190506,4006,1003,40,100
997600970,20190115,4001,1002,25,50
997600970,20190115,4001,1003,40,30
997600970,20190115,4004,1004,40,50
997600970,20190415,4002,1004,40,95
997600970,20190415,4003,1005,40,100
997600970,20181212,4004,1001,25,47
997600970,20181213,4004,1001,25,47
874136439,20190808,4002,1002,25,50
874136439,20190808,4002,1003,40,60
874136439,20190910,4002,1004,40,95
874136439,20190910,4002,1005,60,90
874136439,20191001,4003,1002,25,50
874136439,20191002,4003,1002,25,50

我需要获取某个日期范围内的总访问次数,并且需要将访问次数和结果结合起来才能获得(例如)同一日期的ipay结果总和。

我得到这样的查询:

SELECT X.NumberOfVisits, SUM(Y.ipay) TotalIPay
FROM (  
        (SELECT *, COUNT(*) NumberOfVisits
         FROM visit
         WHERE (vdate >=20190101 AND vdate <=20190331)
        ) X
        JOIN
        (SELECT *
         FROM outcome
        ) Y
        ON (X.vdate = Y.vdate)
    );

它不起作用。

如果我将查询分为几个单独的查询:

SELECT X.OverallNumberOfVisits
FROM (  
        (SELECT COUNT(*) OverallNumberOfVisits
         FROM visit
         WHERE (vdate >=20190101 AND vdate <=20190331)
        ) X
     );

SELECT SUM(Y.ipay) TotalIPay
FROM (  
        (SELECT *
         FROM visit
         WHERE (vdate >=20190101 AND vdate <=20190331)
        ) X
        JOIN
        (SELECT *
         FROM outcome
        ) Y
        ON (X.vdate = Y.vdate)
    );

然后起作用。但是我不想这样做。我想在一个查询中做到这一点。如何正确组合它们?

1 个答案:

答案 0 :(得分:2)

您的查询似乎过于复杂-子查询过多。如果您有访问ID(即表格上的主键),则可以执行以下操作:

SELECT COUNT(DISTINCT v.visit_id), SUM(o.ipay) TotalIPay
FROM visit v LEFT JOIN
     outcome o
     ON v.vdate = o.vdate
WHERE v.vdate >= 20190101 AND v.vdate <= 20190331;

我怀疑您实际上想同时加入ssnvdate,但是您说您的版本有效。

如果没有主键,则可以执行以下操作:

SELECT MAX(num_visits), SUM(o.ipay) TotalIPay
FROM (SELECT v.*, COUNT(*) OVER () as num_visits
      FROM visit v
      WHERE v.vdate >= 20190101 AND v.vdate <= 20190331
     ) v LEFT JOIN
     outcome o
     ON v.vdate = o.vdate;