[英]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');
試過:
我嘗試了太多東西,無法在此處列出。
我終於找到了克服所有“未知字段”錯誤並至少獲得一些結果的方法,但是:
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 |
關注 | 關注 |
關注 | 關注 |
問題:
COUNT()
聚合數據與CASE
類型條件結合使用?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.