计算其他表中的一个表的字段

时间:2016-05-18 08:03:26

标签: sql oracle

我在oracle中写了一个脚本。但它并没有给我我想要的结果。 我需要这个,想象我有两张桌子。 Order_table和书桌。 我的订单表是这样的

ORDER_TABLE表

ID  TYPE_ID   VALUE_ID 
1    11       null
2    11       null
3    11       null
4    12       null
5    11       null

书桌

ID  ORDER_TYPE    DELETED
1      1         F
2      null      F
3      5         F
4      5         F
5      4         F
6      4         F
7      3         T

我的脚本就像这样

Select *
From (
  Select Newtable.Counter As Value_id,
         o.Id As Id,
         o.Type_id As Type_id
  From   (
           Select (Count B.Order_Type) As Counter, 
                  B.Order_Type As Id
           From   Book B
           Where  B.Deleted = 'F'
           Group By B.Order_Type
           Order By Count(B.Order_Type) Desc
         ) newtable,
         order_table o
  where  o.id = newtable.id
  and    o.type_id = 11
)
order by id asc;

结果是这样的。

Value_ID TYPE_ID ID
2          11     5
2          11     4
1          11     1

没有显示第二个和第三个id有0个计数,我也可以显示0个计数吗?

结果应该是这样的。

Value_ID TYPE_ID ID
2          11     5
2          11     4
1          11     1
0          11     2
0          11     3

3 个答案:

答案 0 :(得分:1)

首先,不要使用隐式JOIN语法(以逗号分隔),这就是这个错误难以捕捉的原因之一!使用正确的JOIN语法。

其次,您的问题是需要left join,而不是inner join,请尝试以下操作:

Select *
  From  (Select coalesce(Newtable.Counter,0) As Value_id,
                o.Id             As Id,
                o.Type_id        As Type_id
         From order_table o
         LEFT JOIN (Select Count(B.Order_Type) As Counter, B.Order_Type As Id
                    From Book B
                    Where B.Deleted = 'F'
                    Group By B.Order_Type
                    Order By Count(B.Order_Type) Desc) newtable
           ON(o.id = newtable.id)
         WHERE o.type_id = 11)
 order by id asc;

答案 1 :(得分:0)

Oracle安装程序

CREATE TABLE order_table ( id, type_id, value_id ) AS
SELECT 1, 11, CAST( NULL AS INT ) FROM DUAL UNION ALL
SELECT 2, 11, CAST( NULL AS INT ) FROM DUAL UNION ALL
SELECT 3, 11, CAST( NULL AS INT ) FROM DUAL UNION ALL
SELECT 4, 12, CAST( NULL AS INT ) FROM DUAL UNION ALL
SELECT 5, 11, CAST( NULL AS INT ) FROM DUAL;

CREATE TABLE book ( id, order_type, deleted ) AS
SELECT 1, 1, 'F' FROM DUAL UNION ALL
SELECT 2, NULL, 'F' FROM DUAL UNION ALL
SELECT 3, 5, 'F' FROM DUAL UNION ALL
SELECT 4, 5, 'F' FROM DUAL UNION ALL
SELECT 5, 4, 'F' FROM DUAL UNION ALL
SELECT 6, 4, 'F' FROM DUAL UNION ALL
SELECT 7, 3, 'T' FROM DUAL;

<强>查询

SELECT COUNT( b.order_type ) AS value_id,
       o.id,
       o.order_type
FROM   order_table o
       LEFT OUTER JOIN
       book b
       ON ( o.id = b.order_type AND b.deleted = 'F' )
WHERE  o.type_id = 11
GROUP BY o.id, o.type_id
ORDER BY value_id DESC, id DESC;

<强>输出

VALUE_ID ID TYPE_ID
-------- -- -------
       2  5      11
       1  1      11
       0  3      11
       0  2      11

但是,如果您确实想使用旧的Oracle逗号连接语法,那么您可以获得相同的结果:

SELECT COUNT( b.order_type ) AS value_id,
       o.id,
       o.order_type
FROM   order_table o,
       book b
WHERE  o.type_id        = 11
AND    b.order_type (+) = o.id
AND    b.deleted    (+) = 'F'
GROUP BY o.id, o.type_id
ORDER BY value_id DESC, id DESC;

不要因为ANSI / ISO连接更容易理解连接条件。

答案 2 :(得分:0)

您也可以使用标量子查询执行此操作,该子查询可能比其他答案中描述的左连接版本更高效,也可能没有。 (很可能,优化器可能会将其重写为左连接!):

with order_table ( id, type_id, value_id ) as (select 1, 11, cast( null as int ) from dual union all
                                               select 2, 11, cast( null as int ) from dual union all
                                               select 3, 11, cast( null as int ) from dual union all
                                               select 4, 12, cast( null as int ) from dual union all
                                               select 5, 11, cast( null as int ) from dual),
          book ( id, order_type, deleted ) as  (select 1, 1, 'F' from dual union all
                                                select 2, null, 'F' from dual union all
                                                select 3, 5, 'F' from dual union all
                                                select 4, 5, 'F' from dual union all
                                                select 5, 4, 'F' from dual union all
                                                select 6, 4, 'F' from dual union all
                                                select 7, 3, 'T' from dual)
-- end of mimicking your tables; you wouldn't need the above subqueries as you already have the tables.
-- See SQL below:
select (select count(*) from book bk where bk.deleted = 'F' and bk.order_type = ot.id) value_id,
       ot.type_id,
       ot.id
from   order_table ot
order by value_id desc,
         id desc;

  VALUE_ID    TYPE_ID         ID
---------- ---------- ----------
         2         11          5
         2         12          4
         1         11          1
         0         11          3
         0         11          2