T-SQL, пропустить нежелательные результаты - PullRequest
1 голос
/ 08 апреля 2011
CREATE TABLE #t(LocationCode varchar(10), ResourceId int, TransType char(3))

INSERT #t
SELECT 'STORE 001', 1, 'In' UNION ALL

SELECT 'STORE 002', 2, 'In' UNION ALL

SELECT 'STORE 003', 3, 'In' UNION ALL

SELECT 'STORE 001', 1, 'Out' UNION ALL
SELECT 'STORE 004', 1, 'In'  UNION ALL

SELECT 'STORE 004', 4, 'In' UNION ALL
SELECT 'STORE 004', 4, 'Out' UNION ALL

SELECT 'STORE 004', 1, 'Out' UNION ALL
SELECT 'STORE 001', 1, 'In'  

DROP TABLE #t

Как показать только элементы с соответствующим местоположением, имеющие максимальное количество «Ins» по сравнению с «Outs» (извините за мой плохой английский).

LocationCode              ResourceId
STORE 001[edited]         1
STORE 002                 2
STORE 003                 3

1 Ответ

6 голосов
/ 08 апреля 2011

Предполагается, что вы хотите только Ins, где нет подходящих Out.

SELECT *
FROM #t AS a
WHERE a.TransType = 'In'
    AND NOT EXISTS (
        SELECT *
        FROM #t AS b
        WHERE b.TransType = 'Out'
            AND b.LocationCode = a.LocationCode
            AND b.ResourceId = a.ResourceId
    )

Вам потребуется больше данных в вашей схеме, чтобы можно было сопоставить выход с входом по времени.

Попробуйте что-нибудь попроще, как это:

SELECT LocationCode, ResourceID
FROM #t
GROUP BY LocationCode, ResourceID
HAVING COUNT(*) % 2 = 1

Вот пример, где транзакции упорядочены и два способа использовать эту последовательность:

CREATE TABLE #t(LocationCode varchar(10), ResourceId int, TransType char(3), Seq int UNIQUE NOT NULL)

INSERT #t
SELECT 'STORE 001', 1, 'In', 1 UNION ALL
SELECT 'STORE 002', 2, 'In', 2 UNION ALL
SELECT 'STORE 003', 3, 'In', 3 UNION ALL
SELECT 'STORE 001', 1, 'Out', 4 UNION ALL
SELECT 'STORE 004', 1, 'In', 5 UNION ALL
SELECT 'STORE 004', 4, 'In', 6 UNION ALL
SELECT 'STORE 004', 4, 'Out', 7 UNION ALL
SELECT 'STORE 004', 1, 'Out', 8 UNION ALL
SELECT 'STORE 001', 1, 'In', 9 

;WITH Ins AS (
SELECT * FROM #t
WHERE TransType = 'In'
)
,Outs AS (
SELECT * FROM #t
WHERE TransType = 'Out'
)
,Matched AS (
SELECT *,
(SELECT MIN(Seq)
FROM Outs
WHERE Outs.LocationCode = Ins.LocationCode
AND Outs.ResourceID = Ins.ResourceID
AND Outs.Seq > Ins.Seq) AS OutSeq
FROM Ins
)
SELECT *
FROM Matched
WHERE OutSeq IS NULL

;WITH LastIn AS (
SELECT ResourceID, MAX(Seq) AS Seq
FROM #t
WHERE TransType = 'In'
GROUP BY ResourceID
)
SELECT *
FROM LastIn
WHERE NOT EXISTS (
SELECT *
FROM #t outs
WHERE outs.TransType = 'Out'
AND Outs.ResourceID = LastIn.ResourceID
AND outs.Seq > LastIn.Seq)

DROP TABLE #t​​​​​​​​​​​
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...