如何取消透视多列并从任一列中排除值?
How can I unpivot multiple columns and exclude values from either column?
我有一个 table,其中包含一个 id
和两个产品列,product
和 product_other
。 product
列可能有一个有效的产品名称,单词 "other",或者是空白,因为它来自源。如果 product
为 "other",则 product_other
应具有有效的产品名称,否则可能为空或随机包含有效的产品名称。
我需要将所有有效的产品名称拉到一个列中,并排除空白和 "other" 条目。到目前为止,我已经尝试了两种方法,UNION
方法如下:
SELECT DISTINCT * FROM
(
SELECT id
, COALESCE(NULLIF(NULLIF(product, 'other'), ''), 'UNKNOWN') AS product
FROM myTable
UNION
SELECT id
, COALESCE(NULLIF(product_other, ''), 'UNKNOWN') AS product
FROM myTable
) k
ORDER BY id
这会生成所有行,包括 product
的 'UNKNOWN' 值和相同 id
的 product_other
的有效产品名称,而它应该只提供有效名称如果有的话。
我使用的另一种方法是下面的 CASE WHEN
方法:
SELECT id
, CASE COALESCE(NULLIF(product, ''), 'UNKNOWN')
WHEN 'other' THEN COALESCE(NULLIF(product_other, ''), 'UNKNOWN')
ELSE COALESCE(NULLIF(product_other, ''), 'UNKNOWN')
END AS product
FROM myTable
ORDER BY id
但是,这个只生成了可用的有效 product
列表,或者当 product
为 "other" 或空白时生成了 product_other
列表。它排除了存在有效 product
product 和 product_other 值的情况的可能性。
另一种看待它的方法是,如果您 SELECT id, count(*) FROM (
以 k ) GROUP BY id
查询,第一种情况下会有计数为 2 的行,无论一个是 "UNKNOWN"或不,第二个总是每个 id
.
只有 1 行
所以,myTable
看起来像这样:
id product product_other
------ --------- ---------------
155535 OTC COM
155536 OTC
155537 other COM
155538
我希望查询结果如下所示:
id product
------ ---------
155535 OTC
155535 COM
155536 OTC
155537 COM
155538 UNKNOWN
谢谢。
试试这个:
CREATE TABLE #temp (id int , product varchar(10), product_other VARCHAR(10))
INSERT INTO #temp
VALUES(155535,'OTC','COM'),
(155536, '' ,'OTC'),
(155537,'other','COM'),
(155538,'','')
SELECT id
, CASE WHEN COALESCE(NULLIF(product, ''),NULLIF(product_other, '')) = 'other' AND NULLIF(product_other, '') IS NOT NULL THEN product_other
WHEN COALESCE(NULLIF(product, ''),NULLIF(product_other, '')) IS NULL AND NULLIF(product_other, '') IS NULL THEN 'UNKNOWN'
ELSE COALESCE(NULLIF(product, ''),NULLIF(product_other, '')) END AS product
FROM #temp
UNION
SELECT id
,CASE WHEN COALESCE(NULLIF(product_other, ''),NULLIF(product, '')) = 'other' AND NULLIF(product, '') IS NOT NULL THEN product_other
WHEN COALESCE(NULLIF(product_other, ''),NULLIF(product, '')) IS NULL AND NULLIF(product, '') IS NULL THEN 'UNKNOWN'
ELSE COALESCE(NULLIF(product_other, ''),NULLIF(product, '')) END AS product
FROM #temp;
结果:
所以本质上是这样的逻辑:
SELECT id
, CASE WHEN COALESCE(NULLIF(product, ''),NULLIF(product_other, '')) = 'other' AND NULLIF(product_other, '') IS NOT NULL THEN product_other
WHEN COALESCE(NULLIF(product, ''),NULLIF(product_other, '')) IS NULL AND NULLIF(product_other, '') IS NULL THEN 'UNKNOWN'
ELSE COALESCE(NULLIF(product, ''),NULLIF(product_other, '')) END AS product
FROM myTable
UNION
SELECT id
,CASE WHEN COALESCE(NULLIF(product_other, ''),NULLIF(product, '')) = 'other' AND NULLIF(product, '') IS NOT NULL THEN product_other
WHEN COALESCE(NULLIF(product_other, ''),NULLIF(product, '')) IS NULL AND NULLIF(product, '') IS NULL THEN 'UNKNOWN'
ELSE COALESCE(NULLIF(product_other, ''),NULLIF(product, '')) END AS product
FROM myTable;
SELECT *
FROM myTable
UNPIVOT(product_name FOR product_type IN (product, product_other)) u
WHERE
u.product_name NOT IN ('', 'other');
我有一个 table,其中包含一个 id
和两个产品列,product
和 product_other
。 product
列可能有一个有效的产品名称,单词 "other",或者是空白,因为它来自源。如果 product
为 "other",则 product_other
应具有有效的产品名称,否则可能为空或随机包含有效的产品名称。
我需要将所有有效的产品名称拉到一个列中,并排除空白和 "other" 条目。到目前为止,我已经尝试了两种方法,UNION
方法如下:
SELECT DISTINCT * FROM
(
SELECT id
, COALESCE(NULLIF(NULLIF(product, 'other'), ''), 'UNKNOWN') AS product
FROM myTable
UNION
SELECT id
, COALESCE(NULLIF(product_other, ''), 'UNKNOWN') AS product
FROM myTable
) k
ORDER BY id
这会生成所有行,包括 product
的 'UNKNOWN' 值和相同 id
的 product_other
的有效产品名称,而它应该只提供有效名称如果有的话。
我使用的另一种方法是下面的 CASE WHEN
方法:
SELECT id
, CASE COALESCE(NULLIF(product, ''), 'UNKNOWN')
WHEN 'other' THEN COALESCE(NULLIF(product_other, ''), 'UNKNOWN')
ELSE COALESCE(NULLIF(product_other, ''), 'UNKNOWN')
END AS product
FROM myTable
ORDER BY id
但是,这个只生成了可用的有效 product
列表,或者当 product
为 "other" 或空白时生成了 product_other
列表。它排除了存在有效 product
product 和 product_other 值的情况的可能性。
另一种看待它的方法是,如果您 SELECT id, count(*) FROM (
以 k ) GROUP BY id
查询,第一种情况下会有计数为 2 的行,无论一个是 "UNKNOWN"或不,第二个总是每个 id
.
所以,myTable
看起来像这样:
id product product_other
------ --------- ---------------
155535 OTC COM
155536 OTC
155537 other COM
155538
我希望查询结果如下所示:
id product
------ ---------
155535 OTC
155535 COM
155536 OTC
155537 COM
155538 UNKNOWN
谢谢。
试试这个:
CREATE TABLE #temp (id int , product varchar(10), product_other VARCHAR(10))
INSERT INTO #temp
VALUES(155535,'OTC','COM'),
(155536, '' ,'OTC'),
(155537,'other','COM'),
(155538,'','')
SELECT id
, CASE WHEN COALESCE(NULLIF(product, ''),NULLIF(product_other, '')) = 'other' AND NULLIF(product_other, '') IS NOT NULL THEN product_other
WHEN COALESCE(NULLIF(product, ''),NULLIF(product_other, '')) IS NULL AND NULLIF(product_other, '') IS NULL THEN 'UNKNOWN'
ELSE COALESCE(NULLIF(product, ''),NULLIF(product_other, '')) END AS product
FROM #temp
UNION
SELECT id
,CASE WHEN COALESCE(NULLIF(product_other, ''),NULLIF(product, '')) = 'other' AND NULLIF(product, '') IS NOT NULL THEN product_other
WHEN COALESCE(NULLIF(product_other, ''),NULLIF(product, '')) IS NULL AND NULLIF(product, '') IS NULL THEN 'UNKNOWN'
ELSE COALESCE(NULLIF(product_other, ''),NULLIF(product, '')) END AS product
FROM #temp;
结果:
所以本质上是这样的逻辑:
SELECT id
, CASE WHEN COALESCE(NULLIF(product, ''),NULLIF(product_other, '')) = 'other' AND NULLIF(product_other, '') IS NOT NULL THEN product_other
WHEN COALESCE(NULLIF(product, ''),NULLIF(product_other, '')) IS NULL AND NULLIF(product_other, '') IS NULL THEN 'UNKNOWN'
ELSE COALESCE(NULLIF(product, ''),NULLIF(product_other, '')) END AS product
FROM myTable
UNION
SELECT id
,CASE WHEN COALESCE(NULLIF(product_other, ''),NULLIF(product, '')) = 'other' AND NULLIF(product, '') IS NOT NULL THEN product_other
WHEN COALESCE(NULLIF(product_other, ''),NULLIF(product, '')) IS NULL AND NULLIF(product, '') IS NULL THEN 'UNKNOWN'
ELSE COALESCE(NULLIF(product_other, ''),NULLIF(product, '')) END AS product
FROM myTable;
SELECT *
FROM myTable
UNPIVOT(product_name FOR product_type IN (product, product_other)) u
WHERE
u.product_name NOT IN ('', 'other');