这个SQL有什么问题?

时间:2016-03-12 22:08:29

标签: sql sql-server tsql

它的SQL Server:

SQL:

SELECT 
    Tb_Supplier.State, Tb_Supplier.City,
    COUNT(DISTINCT Tb_Supplier.Name) as Suppliers
    Tb_Consumer.State, Tb_Consumer.City,
    COUNT(DISTINCT Tb_Consumer.Name) as Consumers

1 个答案:

答案 0 :(得分:1)

SELECT
      COALESCE(s.state, c.state) AS state
    , COALESCE(s.city, c.city) AS city
    , COALESCE(s.Suppliers, 0) AS Suppliers
    , COALESCE(c.Consumers, 0) AS Consumers
FROM (
      SELECT
            Tb_Supplier.State
          , Tb_Supplier.City
          , COUNT(Tb_Supplier.Name) AS Suppliers
      FROM Tb_Supplier
      GROUP BY
            Tb_Supplier.City
          , Tb_Supplier.State
) AS s
      FULL OUTER JOIN (
            SELECT
                  Tb_Consumer.State
                , Tb_Consumer.City
                , COUNT(Tb_Consumer.Name) AS Consumers
            FROM Tb_Consumer
            GROUP BY
                  Tb_Consumer.City
                , Tb_Consumer.State
      ) AS c ON s.state = c.state
                  AND s.city = c.city

上面的查询使用了我认为是"主表"对于供应商和消费者而言,每个行中的行应该唯一定义供应商或消费者。因此,上述方法不需要count(distinct...)。使用full outer join是因为州/城市中的供应商可能没有匹配的消费者,反之亦然。由于此coalesce在最终的select子句中用于处理来自供应商或消费者方的可能的NULL。

为什么你应该停止在表之间使用逗号:

-- Accidental Cross Join? (Cartesian Product)
-- or is it Deliberate
select * from table_one, table_two

在上面的示例中,table_one的每一行与table_two的所有行相乘。因此,如果两个表都有100行,则结果为100 * 100 = 10,000行。我想要10,000行吗?

你不知道我是否想要它,它可能是故意的或只是一个意外。

select * from table_one CROSS JOIN table_two

但现在我知道交叉连接是故意的。

回顾你原来的问题。

FROM 
    Tb_Supplier, Tb_Consumer
GROUP BY 
    Tb_Supplier.City, Tb_Supplier.State, Tb_Consumer.City, Tb_Consumer.State​

如果您有1,000个供应商和100,000个消费者,您在该条款中创建了多少行? (1,000 * 100,000 = 100,000,000)我很确定这是偶然的,这就是为什么你应该停止在from子句中的表之间使用逗号。