簡體   English   中英

有沒有辦法在 CASE 中使用聚合 COUNT() 值?

[英]Is there a way to use aggregate COUNT() values within CASE?

我需要檢索唯一但截斷的零件編號,它們的描述值是有條件確定的。

數據:
以下是一些簡化的示例數據:
(真正的表有半百萬行)

create table inventory(
   partnumber VARCHAR(10),
   description VARCHAR(10)
);
INSERT INTO inventory (partnumber,description) VALUES
    ('12345','ABCDE'),
    ('123456','ABCDEF'),
    ('1234567','ABCDEFG'),
    ('98765','ZYXWV'),
    ('987654','ZYXWVU'),
    ('9876543','ZYXWVUT'),
    ('abcde',''),
    ('abcdef','123'),
    ('abcdefg','321'),
    ('zyxwv',NULL),
    ('zyxwvu','987'),
    ('zyxwvut','789');

試過:
我嘗試了太多東西,無法在此處列出。
終於找到了克服所有“未知字段”錯誤並至少獲得一些結果的方法,但是:

  1. 超級笨拙!
  2. 我的結果不僅限於獨特的prod

這是我當前的查詢:

SELECT
  LEFT(i.partnumber, 6) AS prod,
  CASE
    WHEN agg.cnt > 1
    OR i.description IS NULL
    OR i.description = ''
    THEN LEFT(i.partnumber, 6)
    ELSE i.description
  END AS `descrip`
  FROM inventory i
  INNER JOIN (SELECT LEFT(ii.partnumber, 6) t, COUNT(*) cnt
    FROM inventory ii GROUP BY ii.partnumber) AS agg
  ON LEFT(i.partnumber, 6) = agg.t;

目標:
我的目標是檢索:

產品 描述
12345 ABCDE
123456 123456
98765 ZYXWV
987654 987654
abcde abcde
abcdef abcdef
關注 關注
關注 關注

問題:

  1. 有哪些更簡潔的方法可以將COUNT()聚合數據與CASE類型條件結合使用?
  2. 如何限制我的結果以使所有prod都是唯一的?

您可以通過檢查count(*) > 1來檢查結果中的left(partnumber, 6)是否不唯一。 在這種情況下,讓 descript 為left(partnumber, 6) descrip 否則,您可以使用max(description) (或min(description) )來獲取單個描述,但滿足對不在GROUP BY中的列使用聚合 function 的需要。 要替換空或NULL描述,可以使用nullif()coalesce()

這將導致以下僅使用一級聚合而不使用連接:

SELECT left(partnumber, 6) AS prod,
       CASE
         WHEN count(*) > 1 THEN
           left(partnumber, 6)
         ELSE
           coalesce(nullif(max(description), ''), left(partnumber, 6))
       END AS descrip
       FROM inventory
       GROUP BY left(partnumber, 6)
       ORDER BY left(partnumber, 6);

但是 MySQL 中似乎有一個錯誤,此查詢失敗。 引擎沒有“看到”,在partnumber之后的列表中, SELECT僅用於表達式left(partnumber, 6) ,該表達式也在GROUP BY中。 相反,引擎錯誤地抱怨部件號不在GROUP BY中並且不受聚合partnumber的約束。

作為一種解決方法,我們可以使用派生表,它將partnumber縮短為其前六個字符。 然后,我們使用派生表的該列而不是left(partnumber, 6)

SELECT l6pn AS prod,
       CASE
         WHEN count(*) > 1 THEN
           l6pn
         ELSE
           coalesce(nullif(max(description), ''), l6pn)
       END AS descrip
       FROM (SELECT left(partnumber, 6) AS l6pn,
                    description
                    FROM inventory) AS x
       GROUP BY l6pn
       ORDER BY l6pn;

或者我們在left(partnumber, 6)周圍拍一些實際上毫無意義的max() es,而不是第一個,以解決這個錯誤。

SELECT left(partnumber, 6) AS prod,
       CASE
         WHEN count(*) > 1 THEN
           max(left(partnumber, 6))
         ELSE
           coalesce(nullif(max(description), ''), max(left(partnumber, 6)))
       END AS descrip
       FROM inventory
       GROUP BY left(partnumber, 6)
       ORDER BY left(partnumber, 6);

db<>fiddle (將 DBMS 更改為 Postgres 或 MariaDB 等其他數據庫,以查看它們是否也接受第一個查詢。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM