根据 SQL 中的行创建类别
Creating categories based on rows in SQL
我有以下 table 称为 "Animal"。
Animal Drink
Dog Water
Dog Water
Dog Water
Cat Milk
Cat Milk
Cat Water
我正在尝试根据动物饮用的饮料类型创建类别,结果将是。
Animal Drink
Dog Water
Cat Mixed
我尝试过各种案例陈述,但都没有成功。问题是我比较的是行(而不是列),事实证明这对我来说相当困难。
基本上,我想挑出只喝水的动物。
如果一只动物只喝水,那么它将被归类为 "Water"。如果一只动物喝水和其他任何东西,那么它将被归类为 "Mixed"。如果动物不喝任何水,那么它将被归类为 "NonWater"
为此,您可以简单地使用 group by expression :
SELECT
animal,
CASE
WHEN (sum_other = 0) THEN 'Water'
WHEN (sum_water = 0) THEN 'NonWater'
ELSE 'Mixed'
END
FROM (SELECT
animal,
SUM(CASE
WHEN (drink = 'Water') THEN 1
ELSE 0
END) AS sum_water,
SUM(CASE
WHEN (drink <> 'Water') THEN 1
ELSE 0
END) AS sum_other
FROM my_table
GROUP BY animal) A
可能看起来很复杂,但我认为可以,虽然我没有测试过:
SELECT
A.[Animal]
, [Drink] = IIF(A.[Cnt] > 1, 'Mixed', T.[Drink])
FROM
(
SELECT
[Animal]
, [Cnt] = Count(*)
FROM
[Table]
GROUP BY
[Animal]
, [Drink]
) AS A
OUTER APPLY(
SELECT TOP 1
*
FROM
[Table] AS T
WHERE
A.Animal = T.Animal
) AS T
按动物和用例计算饮料数量:
SELECT Animal,
CASE WHEN COUNT(DISTINCT Drink)=1
THEN Drink ELSE 'Mixed' END AS Drink
FROM T
GROUP BY Animal
可能是这样的:
SELECT
t.Animal
,'Mixed'
FROM #TEMP t
GROUP BY t.Animal HAVING count(DISTINCT t.Drink) > 1
UNION ALL
SELECT
t.Animal
,(SELECT Top 1 t1.Drink FROM #TEMP t1 WHERE t1.Animal = t.Animal)
FROM #TEMP t
GROUP BY t.Animal HAVING COUNT(DISTINCT t.Drink) = 1
或类似这样的东西
select animal, drink from
(select animal,
rank() over (partition by animal order by drink desc) as rn,
case when rank() over (partition by animal order by drink ) = 1
then drink
else 'mixed'
end as drink
from animal
)x
where x.rn = 1
group by 1, 2
简单的解决方案:
SELECT Animal,
CASE WHEN COUNT(DISTINCT Drink)=1
THEN
(SELECT DISTINCT Drink from my_table where Animal = T.Animal)
ELSE 'Mixed' END AS Drink
FROM my_table as T
GROUP BY Animal
我有以下 table 称为 "Animal"。
Animal Drink
Dog Water
Dog Water
Dog Water
Cat Milk
Cat Milk
Cat Water
我正在尝试根据动物饮用的饮料类型创建类别,结果将是。
Animal Drink
Dog Water
Cat Mixed
我尝试过各种案例陈述,但都没有成功。问题是我比较的是行(而不是列),事实证明这对我来说相当困难。
基本上,我想挑出只喝水的动物。 如果一只动物只喝水,那么它将被归类为 "Water"。如果一只动物喝水和其他任何东西,那么它将被归类为 "Mixed"。如果动物不喝任何水,那么它将被归类为 "NonWater"
为此,您可以简单地使用 group by expression :
SELECT
animal,
CASE
WHEN (sum_other = 0) THEN 'Water'
WHEN (sum_water = 0) THEN 'NonWater'
ELSE 'Mixed'
END
FROM (SELECT
animal,
SUM(CASE
WHEN (drink = 'Water') THEN 1
ELSE 0
END) AS sum_water,
SUM(CASE
WHEN (drink <> 'Water') THEN 1
ELSE 0
END) AS sum_other
FROM my_table
GROUP BY animal) A
可能看起来很复杂,但我认为可以,虽然我没有测试过:
SELECT
A.[Animal]
, [Drink] = IIF(A.[Cnt] > 1, 'Mixed', T.[Drink])
FROM
(
SELECT
[Animal]
, [Cnt] = Count(*)
FROM
[Table]
GROUP BY
[Animal]
, [Drink]
) AS A
OUTER APPLY(
SELECT TOP 1
*
FROM
[Table] AS T
WHERE
A.Animal = T.Animal
) AS T
按动物和用例计算饮料数量:
SELECT Animal,
CASE WHEN COUNT(DISTINCT Drink)=1
THEN Drink ELSE 'Mixed' END AS Drink
FROM T
GROUP BY Animal
可能是这样的:
SELECT
t.Animal
,'Mixed'
FROM #TEMP t
GROUP BY t.Animal HAVING count(DISTINCT t.Drink) > 1
UNION ALL
SELECT
t.Animal
,(SELECT Top 1 t1.Drink FROM #TEMP t1 WHERE t1.Animal = t.Animal)
FROM #TEMP t
GROUP BY t.Animal HAVING COUNT(DISTINCT t.Drink) = 1
或类似这样的东西
select animal, drink from
(select animal,
rank() over (partition by animal order by drink desc) as rn,
case when rank() over (partition by animal order by drink ) = 1
then drink
else 'mixed'
end as drink
from animal
)x
where x.rn = 1
group by 1, 2
简单的解决方案:
SELECT Animal,
CASE WHEN COUNT(DISTINCT Drink)=1
THEN
(SELECT DISTINCT Drink from my_table where Animal = T.Animal)
ELSE 'Mixed' END AS Drink
FROM my_table as T
GROUP BY Animal