如何从具有多个SET依赖关系的MSSQL表中选择记录?

时间:2018-03-05 07:27:26

标签: sql sql-server tsql

我的表结构/数据是这个

Itemid    RechTyp PstNr  InvoicNr   

1          M       200   Null
2          B       200   84684
3          B       300   84684
4          B       400   84684
5          M       500   Null
6          B       500   84685
7          B       600   84685
8          B       700   84685 

列ItemID是唯一键。列PstNr是ItemID 1&的参考。 2 InvoiceNumber是ItemID 2,3& S的唯一参考。 4.每一套。第一个M和B记录由PstNr统一。

我需要一个可以选择这4条记录的查询。请记住,该表包含超过10,000条带有这组记录的记录。  我正在考虑使用cet&分区功能但我仍在处理查询。

我的预期结果是:见下表 表MyTransaction具有为每个select语句更新的状态行,因此基于itemID的选择将不起作用。 Becasue我没有保证如何插入数据。 ItemId 3可能在最后一行。

RechTyp   PstNr    InvioceNr
M       200   Null
B       200   84684
B       300   84684
B       400   84684

3 个答案:

答案 0 :(得分:2)

这适用于小型表,但在大型记录表中可能会出现性能问题:

DECLARE @TEMP TABLE (Itemid INT, RechTyp NVARCHAR(1), PstNr INT, InvoicNr INT NULL)
INSERT INTO @TEMP VALUES
(1,'M',200,   Null),
(2,'B',200,   84684),
(3,'B',300,   84684),
(4,'B',400,   84684),
(5,'M',500,   Null),
(6,'B',500,   84685),
(7,'B',600,   84685),
(8,'B',700,   84685)

DECLARE @INVOICE INT = 84684

SELECT *
FROM @TEMP
WHERE InvoicNr = @INVOICE
OR PstNr IN (
            SELECT PstNr
            FROM @TEMP
            WHERE InvoicNr = @INVOICE)

输出:

Itemid  RechTyp PstNr   InvoicNr
1   M   200 NULL
2   B   200 84684
3   B   300 84684
4   B   400 84684

答案 1 :(得分:1)

假设我理解了这个问题,您希望获得与特定发票号相关联的所有记录,问题是其中一条记录的InvoiceNr列中没有值,但您可以使用PstNr列标识它。

我认为这可以让你得到理想的结果:

;WITH CTE AS 
(
    SELECT RechTyp, PstNr, InvioceNr
    FROM Table
    WHERE InvioceNr = @InvioceNr
)

SELECT RechTyp, PstNr, InvioceNr
FROM CTE

UNION ALL

SELECT RechTyp, PstNr, InvioceNr
FROM Table
WHERE PstNr IN(SELECT PstNr FROM CTE)

ORDER BY PstNr, InvioceNr

答案 2 :(得分:1)

这是对我有用的答案。我不是工会和加入的粉丝他们更加资源密集。

;With cte_get_invoice (ItemID ,RechTyp, InvoicNr, PstNr ,rownumber)
AS
(
SELECT ItemID ,RechTyp, InvoicNr, PstNr, row_number()over(partition by PstNr
                 ORDER BY RechTyp, InvoicNr, PstNr) 
                as rank from  TransactionTable
)

 select  RechTyp, InvoicNr, PstNr FROM TransactionTable
 where PstNr = (select top(1) PstNr from cte_get_invoice where rownumber  > 1 )
 or InvoicNr = (select top(1) InvoicNr from cte_get_invoice where rownumber  > 1 )