我有一个查询输出结果如下:
Person Food
====== ======
Abner Apple
Beth Banana
Beth Peach
Carlos Grape
Carlos Kiwi
Carlos Strawberry
. . . .
即,它将一个人与一种或多种食物联系起来。我希望聚合函数的功能可以选择食物,但内置的聚合(SUM,MAX,MIN等)都不适用于这种情况。
如果我有一个函数F(),给定食物清单,可以:
有什么方法可以直接将GROUP BY应用到它上面吗?
有没有人有一个查询示例以其他方式执行此操作,以防这是一个白日梦?
= = = =
编辑:让我们说在上面显示的选项中,最佳列表是{Kiwi,Grape,Banana,Strawberry,Apple,Peach},然后输出应该说:
Abner Apple
Beth Banana
Carlos Kiwi
,即每个人一条记录,每个食物的食物是原始表格中与该人物相关的最佳食物清单中的第一个。
答案 0 :(得分:2)
SELECT DISTINCT t.Person, f.Food FROM MyTable AS t
CROSS APPLY(
SELECT TOP 1 Food FROM MyTable AS t1 WHERE t.Person = t1.Person
ORDER BY <your method of rating and choosing goes here>
) AS f
答案 1 :(得分:1)
你的意思是,你想连接这些食物吗?
试试这个:
select p.Person, stuff((select ', ' + f.Food [text()] from Food f where f.PersonId = p.Id order by f.Food for xml path('')),1,2,'') [Foods]
from Person p
答案 2 :(得分:1)
请注意,在我的查询中,您可以使用F()行集返回函数替换OptimalFood
表(如果我理解正确的话)。
WITH PersonFood (Name, Food) AS (
SELECT 'Abner', 'Apple'
UNION ALL SELECT 'Beth', 'Banana'
UNION ALL SELECT 'Beth', 'Peach'
UNION ALL SELECT 'Carlos', 'Grape'
UNION ALL SELECT 'Carlos', 'Kiwi'
UNION ALL SELECT 'Carlos', 'Strawberry'
UNION ALL SELECT 'Delilah', 'Passionfruit'
), OptimalFood (Priority, Food) AS (
SELECT 1, 'Kiwi'
UNION ALL SELECT 2, 'Grape'
UNION ALL SELECT 3, 'Banana'
UNION ALL SELECT 4, 'Strawberry'
UNION ALL SELECT 5, 'Apple'
UNION ALL SELECT 6, 'Peach'
), Choices AS (
SELECT
Selector = Row_Number() OVER (PARTITION BY F.Name ORDER BY Coalesce(O.Priority, 2147483647)),
F.Name,
Food = Coalesce(O.Food, '<None>')
FROM
PersonFood F
LEFT JOIN OptimalFood O ON F.Food = O.Food
)
SELECT
Name,
Food
FROM Choices
WHERE Selector = 1;
如果您的桌子上已列出所有人,则可能是更好的方式:
WITH PersonFood (Name, Food) AS (
SELECT 'Abner', 'Apple'
UNION ALL SELECT 'Beth', 'Banana'
UNION ALL SELECT 'Beth', 'Peach'
UNION ALL SELECT 'Carlos', 'Grape'
UNION ALL SELECT 'Carlos', 'Kiwi'
UNION ALL SELECT 'Carlos', 'Strawberry'
UNION ALL SELECT 'Delilah', 'Passionfruit'
), OptimalFood (Priority, Food) AS (
SELECT 1, 'Kiwi'
UNION ALL SELECT 2, 'Grape'
UNION ALL SELECT 3, 'Banana'
UNION ALL SELECT 4, 'Strawberry'
UNION ALL SELECT 5, 'Apple'
UNION ALL SELECT 6, 'Peach'
), Person AS (
SELECT DISTINCT Name FROM PersonFood
)
SELECT
P.Name,
Food = Coalesce(X.Food, '<None>')
FROM
Person P
OUTER APPLY (
SELECT TOP 1 O.Food
FROM
PersonFood F
INNER JOIN OptimalFood O ON F.Food = O.Food
WHERE P.Name = F.Name
ORDER BY O.Priority
) X;
我希望在所有这些情况下你实际上使用数字键而不是varchar字符串。我希望希望。 :)
答案 3 :(得分:0)
你可以不用小组去:
SELECT DISTINCT Person, F(Person) AS FoodFunction FROM TableName
您必须更改功能F(),以便它需要人(不是食物清单)并通过以下方式获取食物清单:
SELECT Food FROM TableName
WHERE Person = @Person