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

问题描述 投票:2回答:3

我的表结构/数据就是这个

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和4的唯一引用。对于每个集合。第一个M和B记录由PstNr统一。

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

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

RechTyp   PstNr    InvioceNr
M       200   Null
B       200   84684
B       300   84684
B       400   84684
sql sql-server tsql
3个回答
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
投票

假设我理解了这个问题,你想得到与特定发票号相关的所有记录,问题是其中一个记录的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

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 )
© www.soinside.com 2019 - 2024. All rights reserved.