【问题标题】:SQL - SELECT with default if nullSQL - 如果为空,则默认选择
【发布时间】:2017-10-04 17:33:18
【问题描述】:

我有一个这样的查询:

SELECT id, name, price, floorplan 
FROM Inventory 
ORDER BY price

这将返回我的Inventory 表中按价格排序的id、名称、价格、平面图。使用此查询,我返回了 3 行,最后一行有一个平面图值,另外两行为空。是否可以获得非空平面图来替换空平面图列?我不想将这些分组,因为我需要返回 3 行。

【问题讨论】:

  • 哇,你给了很多赏金......不过,一个建议,对于 sql 问题的预期结果和当前结果,加上发布你尝试过的内容会有所帮助

标签: sql sql-server


【解决方案1】:

你可以使用像max() over()这样的窗口函数聚合:

select 
    id
  , name
  , price
  , max(floorplan) over () as floorplan
from Inventory 
order by price

rextester 演示:http://rextester.com/GDWH85581

使用此测试设置:

create table inventory (id int, name varchar(32), price decimal(9,2), floorplan int)
insert into inventory values 
 (1,'one',1.01,null)
,(2,'two',2.02,null)
,(3,'three',3.03,1024)

返回:

+----+-------+-------+-----------+
| id | name  | price | floorplan |
+----+-------+-------+-----------+
|  1 | one   | 1.01  |      1024 |
|  2 | two   | 2.02  |      1024 |
|  3 | three | 3.03  |      1024 |
+----+-------+-------+-----------+

【讨论】:

  • 这不需要访问表两次
【解决方案2】:

求平面图的最大值。使用 isnull 函数,将 floorplan 替换为其最大值,只要它为 null。

  SELECT id, 
         name, 
         price, 
         isnull(floorplan, (select max(floorplan) from Inventory) )
    FROM Inventory 
ORDER BY price

【讨论】:

  • isnull 在这里不需要,如果有超过 1 行的值不为 NULL,则此逻辑将失败。然后,它会带回额外的行。最好只使用 max() 并删除条件检查。
  • @scsimon 我只是想理解你的评论。你的意思是它会有一个错误'子查询返回多行'?但是子查询中有一个max函数,所以我们任何时候都不会得到超过一行
  • 对不起,我不清楚。您不会收到错误消息。我只是暗示您的逻辑是将所有 NULL 值替换为该表的最大值。 OP 没有指定是否会有更多具有非空值的行,但如果有,那么我喜欢你的方法仅仅是因为它保持了前几行的完整性。但是,根据示例,您只需要 @SqlZim 建议的内容。
【解决方案3】:
SELECT id, name, price, 
       (SELECT TOP 1 floorplan FROM Inventory WHERE floorplan IS NOT NULL) as [floorplan]
  FROM Inventory

这应该适用于您的 3 行,但如果有更多记录,我会输入 TOP 1。您需要指定要查看的平面图是否超过 1 不为空

【讨论】:

  • 使用没有 ORDER BY 的 TOP 意味着您不关心返回的 哪些 行。结果可能因每个查询@user979331 而异。需要非常谨慎的事情。
  • 那是错误的。没有订单并不意味着您每次都会得到不同的结果。如果没有添加数据,每次都会得到相同的结果。默认情况下,它由集群键排序,在这种情况下应该是 id
  • 您的 如果没有添加数据 违背了 SQL Server 等事务数据库的目的。这是一个大胆的假设。无论如何,你should read this。你选择了最糟糕的方式来解决这个问题。
  • 我读了你的回答,这并没有改变我的评论。
【解决方案4】:

考虑这个例子。我认为子查询应该是相关的。如果没有烘干机得到平面图,但数据中没有。谢谢

    CREATE TABLE Inventory 
    (id int 
    ,name varchar(30)
    ,price money
    ,floorplan char(1)
    )

    insert inventory 
    SELECT 1, 'Washer', 300, NULL
    insert inventory 
    SELECT 1, 'Washer', 330, NULL
    insert inventory 
    SELECT 1, 'Washer', 340, 'Y'
    insert inventory 
    SELECT 2, 'Dryer', 275,  NULL

    SELECT id, name, price, 
        (SELECT TOP 1 floorplan FROM Inventory AS Y WHERE floorplan IS NOT NULL
        AND Y.id = I.id) as [floorplan]
    FROM Inventory AS I

http://sqlfiddle.com/#!6/ca73e6/3

【讨论】:

  • 我认为这与其他答案相同,用户只提到了三行,所以我认为不需要关联
  • 在 sqlfiddle 中粘贴第一个查询,Dryer 的平面图为“Y”。这是正确的行为吗?
猜你喜欢
  • 2011-04-22
  • 2020-03-20
  • 1970-01-01
  • 2012-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多