sql – GROUP BY一列;为另一个选择任意值

前端之家收集整理的这篇文章主要介绍了sql – GROUP BY一列;为另一个选择任意值前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图为每个用户选择一行.我不关心我得到的图像.此查询适用于 MySQL,但不适用于sql Server:
  1. SELECT user.id,(images.path + images.name) as 'image_path'
  2. FROM users
  3. JOIN images ON images.user_id = users.id
  4. GROUP BY users.id

解决方法

到目前为止使用MIN / MAX聚合或ROW_NUMBER发布的解决方案可能效率最低(取决于数据分布),因为在每组选择一个之前,它们通常必须检查所有匹配的行.

使用AdventureWorks sample database来说明,以下查询都为每个ProductID从Transaction History表中选择一个TransactionType和ReferenceOrderID:

使用MIN / MAX聚合

  1. SELECT
  2. p.ProductID,MIN(th.TransactionType + STR(th.ReferenceOrderID,11))
  3. FROM Production.Product AS p
  4. INNER JOIN Production.TransactionHistory AS th ON
  5. th.ProductID = p.ProductID
  6. GROUP BY
  7. p.ProductID;

使用ROW_NUMBER

  1. WITH x AS
  2. (
  3. SELECT
  4. th.ProductID,th.TransactionType,th.ReferenceOrderID,rn = ROW_NUMBER() OVER (PARTITION BY th.ProductID ORDER BY (SELECT NULL))
  5. FROM Production.TransactionHistory AS th
  6. )
  7. SELECT
  8. p.ProductID,x.TransactionType,x.ReferenceOrderID
  9. FROM Production.Product AS p
  10. INNER JOIN x ON x.ProductID = p.ProductID
  11. WHERE
  12. x.rn = 1
  13. OPTION (MAXDOP 1);

使用仅限内部的ANY聚合

  1. SELECT
  2. q.ProductID,q.TransactionType,q.ReferenceOrderID
  3. FROM
  4. (
  5. SELECT
  6. p.ProductID,rn = ROW_NUMBER() OVER (
  7. PARTITION BY p.ProductID
  8. ORDER BY p.ProductID)
  9. FROM Production.Product AS p
  10. JOIN Production.TransactionHistory AS th ON p.ProductID = th.ProductID
  11. ) AS q
  12. WHERE
  13. q.rn = 1;

有关任何汇总的详细信息,请参阅this blog post.

使用具有非确定性TOP的相关子查询

  1. SELECT p.ProductID,(
  2. -- No ORDER BY,so could be any row
  3. SELECT TOP (1)
  4. th.TransactionType + STR( th.ReferenceOrderID,11)
  5. FROM Production.TransactionHistory AS th WITH (FORCESEEK)
  6. WHERE
  7. th.ProductID = p.ProductID
  8. )
  9. FROM Production.Product AS p;

使用CROSS APPLY和TOP(1)

上一个查询需要连接,并为没有事务历史记录的产品返回NULL.使用CROSS APPLY和TOP解决了这两个问题:

  1. SELECT
  2. p.Name,ca.TransactionType,ca.ReferenceOrderID
  3. FROM Production.Product AS p
  4. CROSS APPLY
  5. (
  6. SELECT TOP (1)
  7. th.TransactionType,th.ReferenceOrderID
  8. FROM Production.TransactionHistory AS th WITH (FORCESEEK)
  9. WHERE
  10. th.ProductID = p.ProductID
  11. ) AS ca;

通过最佳索引,并且如果每个用户通常具有许多图像,则APPLY可能是最有效的.

猜你在找的MsSQL相关文章