【问题标题】:SQL: While and Union to unify SELECTsSQL:While 和 Union 来统一 SELECT
【发布时间】:2016-01-14 13:09:20
【问题描述】:

让我们试试这个方法。

如您所见,我有很多 SELECT(我只展示了 3 个,但我有 20 多个),我需要统一所有这些。每次我需要添加一个品牌时,我都必须一个一个地更改所有的选择。这很无聊。

另外,我有超过 10 个品牌(不仅仅是 3 个),我也需要一一输入。如果我可以只更改 1 次并让 WHILE LOOP 为其他 SELECT 完成其余的工作,这还不错。但是,如果我必须为所有 SELECT 更改所有品牌,我会花费很多时间。

DECLARE @COUNTRY varchar(30)
SET @COUNTRY = 'GERMANY'

SELECT * FROM
(SELECT * FROM
    (SELECT
        FOOD_CATEGORY,
        YEAR_SALE,
        CASE WHEN SUM(SALES)=0 THEN 0
        ELSE ROUND(SUM(CASE WHEN FABRICANTE='BRAND A' THEN ROUND(SALES,3) ELSE 0 END)/SUM(SALES),3) 
        END AS Share_A,
        CASE WHEN SUM(SALES)=0 THEN 0
        ELSE ROUND(SUM(CASE WHEN FABRICANTE='BRAND B' THEN ROUND(SALES,3) ELSE 0 END)/SUM(SALES),3)
        END AS Share_B,
        CASE WHEN SUM(SALES)=0 THEN 0
        ELSE ROUND(SUM(CASE WHEN FABRICANTE='BRAND C' THEN ROUND(SALES,3) ELSE 0 END)/SUM(SALES),3)
        END AS Share_C
    FROM tableChicken
    WHERE
        AREA = @COUNTRY
    GROUP BY
        FOOD_CATEGORY,
        YEAR_SALE) AS CHICKEN

UNION

SELECT * FROM

    (SELECT
        FOOD_CATEGORY,
        YEAR_SALE,
        CASE WHEN SUM(SALES)=0 THEN 0
        ELSE ROUND(SUM(CASE WHEN FABRICANTE='BRAND A' THEN ROUND(SALES,3) ELSE 0 END)/SUM(SALES),3) 
        END AS Share_A,
        CASE WHEN SUM(SALES)=0 THEN 0
        ELSE ROUND(SUM(CASE WHEN FABRICANTE='BRAND B' THEN ROUND(SALES,3) ELSE 0 END)/SUM(SALES),3)
        END AS Share_B,
        CASE WHEN SUM(SALES)=0 THEN 0
        ELSE ROUND(SUM(CASE WHEN FABRICANTE='BRAND C' THEN ROUND(SALES,3) ELSE 0 END)/SUM(SALES),3)
        END AS Share_C
    FROM tableSwine
    WHERE
        AREA = @COUNTRY
    GROUP BY
        FOOD_CATEGORY,
        YEAR_SALE) AS SWINE

UNION

SELECT * FROM

    (SELECT
        FOOD_CATEGORY,
        YEAR_SALE,
        CASE WHEN SUM(SALES)=0 THEN 0
        ELSE ROUND(SUM(CASE WHEN FABRICANTE='BRAND A' THEN ROUND(SALES,3) ELSE 0 END)/SUM(SALES),3) 
        END AS Share_A,
        CASE WHEN SUM(SALES)=0 THEN 0
        ELSE ROUND(SUM(CASE WHEN FABRICANTE='BRAND B' THEN ROUND(SALES,3) ELSE 0 END)/SUM(SALES),3)
        END AS Share_B,
        CASE WHEN SUM(SALES)=0 THEN 0
        ELSE ROUND(SUM(CASE WHEN FABRICANTE='BRAND C' THEN ROUND(SALES,3) ELSE 0 END)/SUM(SALES),3)
        END AS Share_C
    FROM tableTurkey
    WHERE
        AREA = @COUNTRY
    GROUP BY
        FOOD_CATEGORY,
        YEAR_SALE) AS TURKEY
) AS MAIN_BASE

ORDER BY FOOD_CATEGORY, YEAR_SALE

我希望现在可以理解了。感谢您的帮助!

【问题讨论】:

  • 你的数据库是mysql还是sql-server?

标签: mysql sql sql-server while-loop union


【解决方案1】:

我知道这是您的代码的简单版本,但您不能这样做。

SELECT Brand
     , SUM(Sales_Kg)  AS Sales_Volume
FROM tblSales
WHERE Year = 2015 
  and ID_Brand IN (1,2,3)  -- ADD THIS LINE
GROUP BY Brand

我真的不明白为什么当group by 已经设置了brand_id 时,你用CASE 使查询复杂化

否则使用临时表保存每个结果SAMPLE

【讨论】:

  • 谢谢胡安。我知道这种方式太容易了,但实际上我的代码要复杂得多。
  • 我使用了几个 CASE,每个品牌一个,然后为每个食品类别选择一个(我在一家大型食品公司工作,我们有多个品牌和类别)。所以,我不想为每个食品类别(鸡肉、香肠、弗兰克、火腿、清淡冷盘等)输入每个品牌名称。我想使用 WHILE 来选择所有类别和品牌,而不必一一键入。所以,我想了解如何在这里使用 WHILE 函数来解决我的问题。
  • 如果你把问题说得太简单,那就是问题所在。我的查询和 Gordon 完全按照您的要求进行。也许您需要对您有问题的其他部分的详细信息提出另一个问题。尝试阅读How to create a Minimal, Complete, and Verifiable example.
  • 再次为您举例,在 sum 中使用 CASE 没有意义,因为不会添加任何内容。 brand_idgroup by 中的所有总和都已经相同。下一个示例应包括品牌和类别,但每个仅包含几个。不需要包括整套。如果为 2-3 工作可能会为 5+ 工作
【解决方案2】:

我觉得逻辑很奇怪,但你可以使用cross join

SELECT Brand,
       (CASE WHEN SUM(Sales_Kg)=0 THEN 0
             ELSE SUM(CASE WHEN ID_Brand = b.id_brand THEN Sales_Kg ELSE 0 END)  
        END) AS Sales_Volume
FROM tblSales s CROSS JOIN
     (SELECT 1 as id_brand UNION ALL SELECT 2 UNION ALL select 3) b
WHERE Year = 2015
GROUP BY Brand, b.id_brand;

您可能还想在select 中包含b.id_brand

【讨论】:

  • @Kreiven 如果您有更复杂的查询。此方法与您的存储过程完全相同。但对我来说,您只需计算每个品牌的 sales_kg 总数。这就是SUM(sales_kg) group by Brand 所做的。
猜你喜欢
  • 2019-03-09
  • 1970-01-01
  • 2016-06-08
  • 2014-04-23
  • 1970-01-01
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 2012-03-06
相关资源
最近更新 更多