简体   繁体   中英

How can I select records from MSSQL table with multiple SET dependencies?

My table structure/data is this

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 

The column ItemID is unique key. The column PstNr is reference for ItemID 1 & 2 While InvoiceNumber is unique reference for ItemID 2,3 & 4. For every set. The first M and B record is unified by PstNr.

I need a query that can select these 4 records. Bearing in mind that the table contains more than 10,000 records with this sets of records. I am thinking of using cet & Partition functions but I am still working on the query.

My Expected result is: See table below The Table MyTransaction , has a status row that is updated for every select statement, hence selecting based on itemID will not work. Becasue I have no gurantee on how the data are inserted. Its possible that ItemId 3 will be in the last row.

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

This could work well with a low-size table, but may have performance issues in a big records table:

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)

Output:

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

Assuming I understand the question, you want to get all the records associated with a specific invoice number, and the problem is that one of these records doesn't have a value in it's InvoiceNr column, but you can identify it using the PstNr column.

I think this should get you your desired results:

;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

This is the answer that work for me. I not a fan of union and join they are more resource intensive.

;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 )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM