SQL使用order by从两个表中计数

时间:2013-05-05 05:04:17

标签: sql oracle

我有两张桌子,比如客户和供应商。让我们说结构如下所示:

Customer
--------------------
ProductID|CustomerID|
+--------+----------+
|   1    |   5000   |
|   1    |   5001   |
|   1    |   5002   |
|   2    |   5003   |
|   3    |   5004   |
|   1    |   5005   |
|   4    |   5006   |

Supplier
-----------------
ProductID|SupplierID|
+--------+----------+
|   1    |   3000   |
|   1    |   3001   |
|   2    |   3002   |
|   2    |   3003   |
|   4    |   3004   |
|   5    |   3005   |
|   6    |   3006   |

现在我需要编写基于ProductID给出计数的查询。所以结果应该像

ProductID| Count(Customer Table) | Count(Supplier Table) |
+--------+-----------------------+-----------------------+
|   1    |          4            |         2             |
|   2    |          1            |         2             |
|   3    |          1            |         0             |
|   4    |          1            |         1             |
|   5    |          0            |         1             |
|   6    |          0            |         1             |

这个表只是场景。我的实际表格非常不同。但对此的回答将足以解决我的问题。

2 个答案:

答案 0 :(得分:2)

SELECT  ProductID,
        SUM(CASE WHEN Source = 'C' THEN 1 ELSE 0 END) AS CustomerCount,
        SUM(CASE WHEN Source = 'S' THEN 1 ELSE 0 END) AS SupplierCount
FROM
    (
        SELECT ProductID, CustomerID AS ID, 'C' AS Source FROM Customer
        UNION ALL
        SELECT ProductID, SupplierID AS ID, 'S' AS Source FROM Supplier
    ) sub
GROUP   BY ProductID

输出

╔═══════════╦═══════════════╦═══════════════╗
║ PRODUCTID ║ CUSTOMERCOUNT ║ SUPPLIERCOUNT ║
╠═══════════╬═══════════════╬═══════════════╣
║         1 ║             4 ║             2 ║
║         2 ║             1 ║             2 ║
║         3 ║             1 ║             0 ║
║         4 ║             1 ║             1 ║
║         5 ║             0 ║             1 ║
║         6 ║             0 ║             1 ║
╚═══════════╩═══════════════╩═══════════════╝

答案 1 :(得分:0)

这种情况称为“断层陷阱”,需要在执行连接之前将不同的表聚合到连接列的级别。

您可以通过内联视图执行此操作,尽管对于大型数据集,一对公用表表达式更灵活。

在这种情况下,您可以拥有一个已经提供但未购买的产品,因此我会进行外部联接,以确保您不会丢失任何行:

with
  cte_customers as (
    select   product_id,
             count(*) customer_count
    from     customer
    group by product_id),
  cte_suppliers as (
    select   product_id,
             count(*) supplier_count
    from     supplier
    group by product_id)
select
  s.product_id,
  s.supplier_count,
  coalesce(c.customer_count,0) customer_count
from
  cte_suppliers s left outer join 
  cte_customers on (s.product_id = c.product_id)