如何阻止SQL Server查询在此查询中为同一项ID返回多行

时间:2014-01-15 23:10:07

标签: sql sql-server

首先让我这样说:我无法使用Distinct关键字。返回的数据中存在无法比较的列类型。

这是我的问题:

SELECT
    tblTemp.maxBid, tblAbsentee.abs_bid_price, 
    tblAbsentee.abs_date, tblSale.sale_name, tblSale.sale_date,
    tblItem.*,
    tblTemp.bid_count
FROM 
    tblAbsentee 
INNER JOIN 
    tblItem ON tblAbsentee.abs_item_id = tblItem.item_id AND tblAbsentee.abs_sale_id = tblItem.item_sale_id 
INNER JOIN 
    tblBidder ON tblAbsentee.abs_bidder_id = tblBidder.bidder_number AND tblAbsentee.abs_sale_id = tblBidder.bidder_sale_id 
LEFT JOIN 
    tblSale ON tblAbsentee.abs_sale_id = tblSale.sale_id 
INNER JOIN 
    (SELECT 
        COUNT(tblAbsentee.abs_id) As bid_count, 
        CASE 
            WHEN NOT (MAX(tblAbsentee.abs_bid_price) IS NULL) THEN MAX(tblAbsentee.abs_bid_price) ELSE 0 
        END As maxBid, 
        tblItem.item_id 
     FROM 
        tblAbsentee 
     INNER JOIN 
        tblItem ON tblAbsentee.abs_item_id = tblItem.item_id AND tblAbsentee.abs_sale_id = tblItem.item_sale_id 
     INNER JOIN  
        tblBidder ON tblAbsentee.abs_bidder_id = tblBidder.bidder_number AND tblAbsentee.abs_sale_id = tblBidder.bidder_sale_id 
     LEFT JOIN 
        tblSale ON tblAbsentee.abs_sale_id = tblSale.sale_id 
     WHERE 
        DATEADD(day, 7, tblSale.sale_date) >= GETDATE() 
     GROUP BY
        tblItem.item_id) As tblTemp On tblItem.item_id = tblTemp.item_id AND tblAbsentee.abs_bid_price = tblTemp.maxBid 
WHERE 
    DATEADD(day, 7, tblSale.sale_date) >= GETDATE() 
    AND tblBidder.bidder_mail_id = 13096 
ORDER BY 
    tblItem.item_lot ASC

只要出价人只留下一个出价,这就行得很好。但是,一旦投标人再次出价,我就会收到错误

  

System.Data.ConstraintException:无法启用约束。一行或多行包含违反非null,唯一或外键约束的值。

由于使用数据表作为结果。

以下是一些简短的样本数据:

+--------+-------------+--------------------+-------+
|Max Bid |Abs_bid_price|abs_date            |item_id|
+--------+-------------+--------------------+-------+
|600.0000|600.0000     |1/15/2014 2:40:16 PM|135827 |
+--------+-------------+--------------------+-------+
|600.0000|600.0000     |1/15/2014 2:40:16 PM|135827 |
+--------+-------------+--------------------+-------+
|600.0000|600.0000     |1/15/2014 2:40:16 PM|135827 |
+--------+-------------+--------------------+-------+
|600.0000|600.0000     |1/15/2014 2:40:16 PM|135827 |
+--------+-------------+--------------------+-------+
|600.0000|600.0000     |1/15/2014 2:40:16 PM|135827 |
+--------+-------------+--------------------+-------+
|600.0000|600.0000     |1/15/2014 2:40:16 PM|135827 |
+--------+-------------+--------------------+-------+
|20.0000 |20.0000      |1/15/2014 2:42:16 PM|123562 |
+--------+-------------+--------------------+-------+

我不打算放入所有列。当我说它们都包含相同的数据时,请相信我。在大多数情况下,abs_date列不会完全相同。这只是一个侥幸。在任何一种情况下,我都想按item_id对其进行分组,并在分组时按abs_date字段asc对其进行排序,以便剩下的第一个最大出价将是显示的那个。如果这是MySQL,那很容易。不幸的是,我只是不太了解SQL Server来解决这个问题,并且找不到类似的问题。非常感谢任何帮助。

修改

我的问题可能不太清楚,但我可以有效地返回多行,我只想获得每个项目ID中的一个。

2 个答案:

答案 0 :(得分:3)

您可以使用公用表表达式。这将返回第一个出现的item_id。

;WITH CTE AS
(
    SELECT *, ROW_NUMBER() OVER(PARTITION BY item_id ORDER BY abs_date) Rank
    FROM tblAbsentee
    ...
)
SELECT *
FROM CTE
WHERE Rank = 1

答案 1 :(得分:2)

DECLARE @Table TABLE ([Max Bid] NUMERIC(20,4), Abs_bid_price NUMERIC(20,4),abs_date DATETIME,item_id INT)
INSERT INTO @Table VALUES
(600.0000,    600.0000,    '1/15/2014 2:40:16 PM',    135827),
(600.0000,    600.0000,    '1/15/2014 2:40:16 PM',    135827),
(600.0000,    600.0000,    '1/15/2014 2:40:16 PM',    135827),
(600.0000,    600.0000,    '1/15/2014 2:40:16 PM',    135827)


SELECT * FROM 
(
SELECT * , rn = ROW_NUMBER() OVER (PARTITION BY item_id, [Max Bid] ORDER BY [Max Bid]DESC)
FROM @Table
)Q
WHERE rn = 1

结果集

╔══════════╦═══════════════╦═════════════════════════╦═════════╦════╗
║ Max Bid  ║ Abs_bid_price ║        abs_date         ║ item_id ║ rn ║
╠══════════╬═══════════════╬═════════════════════════╬═════════╬════╣
║ 600.0000 ║ 600.0000      ║ 2014-01-15 14:40:16.000 ║  135827 ║  1 ║
╚══════════╩═══════════════╩═════════════════════════╩═════════╩════╝