当前位置: 首页 > 面试题库 >

如何改善此SQL查询?

符允晨
2023-03-14
问题内容

今天,我遇到了一个有趣的SQL问题,尽管我想出了一个行之有效的解决方案,但我怀疑这是最佳还是最有效的答案。在这里,我请专家-
帮助我学习一些知识并改善查询条件!RDBMS是SQL Server 2008 R2,查询是SSRS报告的一部分,该报告将针对约100,000行运行。

本质上,我有一个ID列表,该ID可能具有多个与之关联的值,这些值是Yes,No或其他字符串。对于ID
x,如果任何值是“是”,则x应该是“是”,如果它们全都是“否”,则它应该是“否”,如果它们包含任何其他值但是和否,则显示该值。我只想为每个ID返回1行,没有重复。

简化版和测试用例:

DECLARE @tempTable table ( ID int, Val varchar(1) )

INSERT INTO @tempTable ( ID, Val ) VALUES ( 10, 'Y')
INSERT INTO @tempTable ( ID, Val ) VALUES ( 11, 'N')
INSERT INTO @tempTable ( ID, Val ) VALUES ( 11, 'N')
INSERT INTO @tempTable ( ID, Val ) VALUES ( 12, 'Y')
INSERT INTO @tempTable ( ID, Val ) VALUES ( 12, 'Y')
INSERT INTO @tempTable ( ID, Val ) VALUES ( 12, 'Y')
INSERT INTO @tempTable ( ID, Val ) VALUES ( 13, 'N')
INSERT INTO @tempTable ( ID, Val ) VALUES ( 14, 'Y')
INSERT INTO @tempTable ( ID, Val ) VALUES ( 14, 'N')
INSERT INTO @tempTable ( ID, Val ) VALUES ( 15, 'Y')
INSERT INTO @tempTable ( ID, Val ) VALUES ( 16, 'Y')
INSERT INTO @tempTable ( ID, Val ) VALUES ( 17, 'F')
INSERT INTO @tempTable ( ID, Val ) VALUES ( 18, 'P')


SELECT DISTINCT t.ID, COALESCE(t2.Val, t3.Val, t4.Val)
FROM @tempTable t
LEFT JOIN
(
    SELECT ID, Val
    FROM @tempTable
    WHERE Val = 'Y'
) t2 ON t.ID = t2.ID
LEFT JOIN
(
    SELECT 
    ID, Val FROM @tempTable
    WHERE Val = 'N'
) t3 ON t.ID = t3.ID
LEFT JOIN
(
    SELECT ID, Val
    FROM @tempTable
    WHERE Val <> 'Y' AND Val <> 'N'
) t4 ON t.ID = t4.ID

提前致谢。


问题答案:

让我们回答一个更简单的问题:对于每个id,获取字母中最后一个的Val。如果Y和N是唯一的值,这将起作用。而且查询要简单得多:

SELECT t.ID, MAX(t.Val) FROM t GROUP BY t.ID;

因此,将您的情况简化为简单的情况。使用枚举(如果数据库支持),或者将值代码分成带有排序规则列的另一个表(在这种情况下,Y可以有1个,N可以有2个,所有其他可能的值可以有999个,并且您希望
最小 )。然后

SELECT ID, c.Val FROM
     (SELECT t.ID, MIN(codes.collation) AS mx
      FROM t join codes on t.Val = codes.Val GROUP BY t.ID) AS q
JOIN codes c ON mx=c.collation;

这里的代码有两列,Val和Collat​​ion。

您也可以使用CTE类型查询来执行此操作,只要您按需要对值进行排序即可。这种方法只有一个联接到一个小的查找表,并且比3个自联接要快得多。

WITH q AS (SELECT t.id, t.Val, ROW_NUMBER() AS r FROM t JOIN codes ON t.Val=codes.Val 
    PARTITION BY t.id ORDER BY codes.collation)
SELECT q.id, q.Val WHERE r=1;


 类似资料:
  • 问题内容: 如何设置邮寄地址的格式,以便始终将所有非空行都推到顶部?也就是说,我想将地址从下面的结构转换为邮寄地址。 结构如下: 以下是一些示例数据: 结果如下所示 (应返回4个不同的字段) : 我正在使用SQL Server 2005。 有人在我们公司写了这个逻辑,看起来似乎很复杂(注意:这不是整个SELECT语句): 问题答案: 这样做的方法是使用UNPIVOT。解决方法如下: 这是输出: 请

  • 问题内容: 有没有一种方法可以改善这种SQL查询性能: 问题是当我的表中有许多数据(如百万行)时,子句的执行非常慢。我必须执行此验证,因为我无法插入重复的数据。 我使用SQLServer 2005 谢谢 问题答案: 确保您正在搜索索引列,而没有操纵这些列中的数据(例如子字符串等)

  • 问题内容: 我有这个MySQL查询,它使用和: 我将如何修改该查询以使其与PostgreSQL一起使用? 问题答案: 这是最新的手册 http://www.postgresql.org/docs/current/static/functions- datetime.html#FUNCTIONS-DATETIME- EXTRACT 顺便说一句:这也是在MySQL上也可以使用的标准(ANSI)SQL。

  • 问题内容: 我有此查询,它运行良好 从此查询中,我从我的位置(这是我的第一张表)中选择所有3 KM的餐厅。 但是我需要从3Km中的食品接头中选择AVG等级。 该查询也运行完美: 但是我需要添加这两个查询,通过它们我可以选择所有那些食品接头及其等级AVG。 问题答案: 只需放置子查询,您将得到结果:

  • 我在索引此查询时遇到问题: 结果是: 我知道它显示0.00秒是执行时间,但此查询将运行多次,它显示它会减慢我的数据库,我不知道为什么! 每次我看到行检查是459448这个查询,所以它在某些原因对我的工作相当糟糕。 有人能给个建议吗?我如何为odata表制作合适的索引?或者我可以使用子查询来修复它? 这些表是: 解释odata: 并解释 wdata: 不得不说wdata.id和odata.vref已

  • 问题内容: 我有一张地图,其中填充了大量数据(大约有300,000条记录) 并如下迭代 } 如上所述,我担心由于在for循环内执行上述操作而导致的性能问题。 更新: 情况是。我正在迭代一个包含大量数据的地图, 在迭代它时,我正在获取用户ID,并且我必须对用户ID进行计算。例如,考虑userid+some constants并应该在数据库表中对其进行更新。 并且还应该与我地图中的列表值一起添加到电子