SQL 查询,允许在尚未出价时对highest_bid列进行 NULL



对于学校,我需要在拍卖网站上制作一个功能。为此,我需要在视图中连接几个表。这工作得很好,直到我需要为价格范围添加一个过滤器。看起来很简单,但是当没有出价时,查询结果需要允许NULL。

观点声明:

SELECT I.itemID, I.title, I.startPrice, B.highestBid, Cfi.category, I.endDate
FROM dbo.Items AS I INNER JOIN dbo.category_for_item AS Cfi ON V.itemID = Vir.itemID 
LEFT OUTER JOIN dbo.Bid AS B ON V.itemID = B.itemID

这将得到下表:

itemID  title   startPrice  highestBid  category    endDate
1   1234    Alfa    25          26          PC          2018-09-22
2   1234    Alfa    25          NULL        PC          2018-09-22
3   5678    Bravo   9           20          Console     2018-07-03
4   5678    Bravo   9           15          Console     2018-07-03
5   5678    Bravo   9           NULL        Console     2018-07-03
6   9876    Charlie 84          100         Stamps      2018-06-14
7   9876    Charlie 84          90          Stamps      2018-06-14
8   9876    Charlie 84          85          Stamps      2018-06-14
9   9876    Charlie 84          NULL        Stamps      2018-06-14
10  1470    Delta   98          100         Fashion     2018-06-15
11  1470    Delta   98          99          Fashion     2018-06-15
12  1470    Delta   98          NULL        Fashion     2018-06-15
13  9631    Echo    56          65          Cars        2018-06-25
14  9631    Echo    56          NULL        Cars        2018-06-25
15  7856    Foxtrot 98          NULL        Dolls       2018-12-26

在四处寻找答案后,我得到了一个关于加入 VIEW 本身的查询,只显示最高出价而不是所有出价:

SELECT VW.itemID, VW.title, VW.startPrice, VW.highestBid, VW.category, VW.endDate
FROM VW_SEARCH AS VW
INNER JOIN (SELECT itemID, MAX(highestBid) AS MaxBid
FROM VW_SEARCH
GROUP BY itemID) VJ
ON VW.itemID = VJ.itemID AND VW.highestBid = VJ.MaxBid

这给出了下一个结果:

itemID  title   startPrice  highestBid  category    endDate
1   1234    Alfa    25          26          PC          2018-09-22
2   5678    Bravo   9           20          Console     2018-07-03
3   9876    Charlie 84          85          Stamps      2018-06-14
4   1470    Delta   98          100         Fashion     2018-06-15
5   9631    Echo    56          65          Cars        2018-06-25

正如我所料,结果仅显示至少有一个出价的项目。我尝试在子查询和连接右外添加了一个额外的条件,以确保我不会得到 itemID 的双倍。

SELECT VW.itemID, VW.title, VW.startPrice, VW.highestBid, VW.category, VW.endDate
FROM VW_SEARCH AS VW
RIGHT OUTER JOIN (SELECT itemID, MAX(highestBid) AS MaxBid
FROM VW_SEARCH
WHERE highestBid > 0 OR highestBid IS NULL
GROUP BY itemID) VJ
ON VW.itemID = VJ.itemID AND VW.highestBid = VJ.MaxBid

这给出了以下结果(没有添加结果 5 - 1199,因为它与结果 4 都相同,这将发生在实际表中,而不是上面的示例表中(:

itemID title   startPrice  highestBid  category    endDate
1       1234    Alfa    25          26          PC          2018-09-22
2       5678    Bravo   9           20          Console     2018-07-03
3       9876    Charlie 84          85          Stamps      2018-06-14
4       NULL    NULL    NULL        NULL        NULL        NULL
1200    1470    Delta   98          100         Fashion     2018-06-15
1201    9631    Echo    56          65          Cars        2018-06-25

虽然这在技术上允许在列中为 NULL,但我需要得到如下结果:

itemID  title   startPrice  highestBid  catgory endDate
1   1234    Alfa    25          26          PC          2018-09-22
2   5678    Bravo   9           20          Console     2018-07-03
3   9876    Charlie 84          85          Stamps      2018-06-14
4   1470    Delta   98          100         Fashion     2018-06-15
5   9631    Echo    56          65          Cars        2018-06-25
6   7856    Foxtrot 98          NULL        Dolls       2018-12-26

我如何获得想要的结果,还是不可能? 另外,如果查询可以写得更好,请说出来。 提前谢谢。

使用left join解决问题:

SELECT VW.itemID, VW.title, VW.startPrice, VW.highestBid, VW.category, VW.endDate
FROM VW_SEARCH VW LEFT JOIN
(SELECT itemID, MAX(highestBid) AS MaxBid
FROM VW_SEARCH
GROUP BY itemID
) VJ
ON VW.itemID = VJ.itemID AND VW.highestBid = VJ.MaxBid;

或者,使用 ANSI 标准ROW_NUMBER()函数:

select vw.*
from (select vw.*,
row_number() over (partition by itemID
order by highestBid nulls last
) as seqnum
from vw_search vw
) vw
where seqnum = 1;

这保证了每个项目一行。

注: 并非所有数据库都支持NULLS LAST。 这甚至可能不是必需的,但您也可以使用case表达式实现它。

您至少可以给出视图的定义吗?也许还有表定义。

我只会选择subquery因为身份列:

select vw.*
from vw_search vw
where id = (select vm1.id
from vw_search vm1
where vm.itemID = vw1.itemID and vm1.highestBid is not null
order by vm1.highestBid desc
limit 1
);

但是,某些DBMS不支持LIMIT子句,例如 SQL Server,如果是这样,则可以改用TOP子句。

相关内容

  • 没有找到相关文章

最新更新