【问题标题】:SQL: Performing a calculation on columns from two select statements in one querySQL:在一个查询中对来自两个选择语句的列执行计算
【发布时间】:2018-04-03 11:28:08
【问题描述】:

我想从两个不相关的 SQL 表(由单独的 SQL 查询形成)中选择信息,给我一个包含四列的表:一个作为标识符,一个用于第一个表中的值,一个用于第二个表中的值,一个用于它们之间的计算。

一个简化的例子是:

已售出

 Shop name | items sold
 Shop A    | 100   
 Shop B    | 50    
 Shop C    | 75    
 Shop D    | 80    

tbl返回

  Shop name | Items returned
  Shop A    | 10
  Shop B    | 5   
  Shop C    | 7 
  Shop D    | 8   

我正在尝试得到一个看起来像这样的表

  Shop name | items sold | items returned | net (sold - returned)
  Shop A    | 100        | 10             | 90
  Shop B    | 50         | 5              | 45
  Shop C    | 75         | 7              | 68
  Shop D    | 80         | 8              | 72

在上述情况下,tblSold 来自如下查询:

SELECT global.shopname, COUNT(stock.sold) 
FROM global
INNER JOIN  stock ON global.id = stock.shop
GROUP BY shopname

而 tblReturned 来自如下查询:

SELECT global.shopname, COUNT(stock.returned) 
FROM global
INNER JOIN  stock ON global.id = stock.shop
WHERE stock.datereturned > 1.01.2010
GROUP BY shopname

从上一个问题SQL: Two select statements in one query 我得到以下查询:

(SELECT global.shopname, COUNT(stock.sold) 
FROM global
INNER JOIN  stock ON global.id = stock.shop
GROUP BY shopname)

UNION

(SELECT global.shopname, COUNT(stock.returned) 
FROM global
INNER JOIN  stock ON global.id = stock.shop
WHERE stock.datereturned > 1.01.2010
GROUP BY shopname)

这给了我一张只有两列的表格,而且无法进行计算。有没有办法以某种方式加入这些以使其发挥作用?

【问题讨论】:

  • 请说明您使用的产品。
  • 感谢您指出这一点 - 抱歉出现错误。这是 Postgres

标签: sql postgresql


【解决方案1】:

我认为你只需要条件聚合:

SELECT g.shopname, COUNT(s.sold),
       SUM(CASE WHEN s.datereturned > '2010-01-01' AND s.returned IS NOT NULL THEN 1 ELSE 0 END) as returned,
       (COUNT(s.sold) - 
        SUM(CASE WHEN s.datereturned > '2010-01-01' AND s.returned IS NOT NULL THEN 1 ELSE 0 END)
       ) as net
FROM global INNER JOIN
     stock
     ON g.id = s.shop
GROUP BY g.shopname;

让日期逻辑只适用于退货很奇怪。另外,我猜你想要的是SUM() 的库存,而不是COUNT()。所以这可能会产生更准确的结果:

SELECT g.shopname, SUM(s.sold) as items_sold,
       SUM(CASE WHEN s.datereturned > '2010-01-01' THEN s.returned ELSE 0 END) as items_returned,
       SUM(CASE WHEN s.datereturned > '2010-01-01' THEN s.items_sold - s.returned
                ELSE s.items_sold END)
FROM global INNER JOIN
     stock
     ON g.id = s.shop
GROUP BY g.shopname;

【讨论】:

    【解决方案2】:
    SELECT t1.shopname,
           t1.items_sold,
           t2.items_returned,(t1.items_sold-t2.items_returned) AS NET 
    FROM (SELECT global.shopname, COUNT(stock.sold) as items_sold
          FROM global
          INNER JOIN  stock ON global.id = stock.shop
          GROUP BY shopname) t1
    INNER JOIN  (SELECT global.shopname, COUNT(stock.returned) as items_returned
                 FROM global
                 INNER JOIN  stock ON global.id = stock.shop
                 WHERE stock.datereturned > '2010-01-01'
                 GROUP BY shopname) t2
    ON t1.shopname = t2.shopname
    

    【讨论】:

      【解决方案3】:

      你可以使用CTE:

      WITH tblSold AS (
          SELECT
            global.shopname,
            COUNT(stock.sold) AS sold
          FROM global
            INNER JOIN stock ON global.id = stock.shop
          GROUP BY shopname),
          tblReturned AS (
            SELECT
              global.shopname,
              COUNT(stock.returned) AS returned
            FROM global
              INNER JOIN stock ON global.id = stock.shop
            WHERE stock.datereturned > '1.01.2010'
            GROUP BY shopname)
      SELECT
        shopname,
        sold,
        returned,
        sold - returned
      FROM tblSold
        INNER JOIN tblReturned USING (shopname);
      

      【讨论】:

        猜你喜欢
        • 2015-11-05
        • 2013-03-01
        • 1970-01-01
        • 2014-07-24
        • 2022-01-09
        • 2021-01-01
        • 2012-01-23
        • 1970-01-01
        • 2011-01-03
        相关资源
        最近更新 更多