Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 tricky query

Author  Topic 

barnabeck
Posting Yak Master

236 Posts

Posted - 2012-01-26 : 06:22:44
The table I have to analize had been corrected for financial issues by the account persons and now I have to filter these actions. The pattern of these operations are easy to recognize, but difficult to translate into SQL - at least for me!

The Query should look for any negative QTY, and omit that line together with the corresponding line that has the same OPID
Table for a specific ORDERID
ORDERID LINE QTY OPID
---------------------------
PDP34533 1 3 4465
PDP34533 2 1 2356
PDP34533 3 2 3512
PDP34533 4 -2 52657
PDP34533 5 2 52657
Select * from TABLE...???

So that the Query should return:
PDP34533  1     3    4465
PDP34533 2 1 2356
PDP34533 3 2 3512
The ommited lines should be double checked by matching both ORDERID AND OPID

Anyone can help me with this?
Regards Martin

sunitabeck
Master Smack Fu Yak Hacker

5155 Posts

Posted - 2012-01-26 : 06:55:17
Would this work for you?
SELECT
OrderId,
Line,
Qty,
Optid
FROM
YourTable y1
WHERE
y1.Opid NOT IN
( SELECT y2.opid FROM YourTable y2
GROUP BY y2.opid
HAVING MIN(y2.Qty) < 0
);
Go to Top of Page

Ifor
Aged Yak Warrior

700 Posts

Posted - 2012-01-26 : 07:03:37
or:


-- *** Test Data ***
CREATE TABLE #t
(
OrderID varchar(20) NOT NULL
,Line tinyint NOT NULL
,Qty smallint NOT NULL
,OPID int NOT NULL
);
INSERT INTO #t
SELECT 'PDP34533', 1, 3, 4465
UNION ALL SELECT 'PDP34533', 2, 1, 2356
UNION ALL SELECT 'PDP34533', 3, 2, 3512
UNION ALL SELECT 'PDP34533', 4, -2, 52657
UNION ALL SELECT 'PDP34533', 5, 2, 52657;
-- *** End Test Data ***

WITH SQtys
AS
(
SELECT OrderId, Line, Qty, OPID
,SUM(Qty) OVER (PARTITION BY OrderID, OPID) AS SQty
FROM #t
)
SELECT OrderId, Line, Qty, OPID
FROM SQtys
WHERE SQty <> 0
ORDER BY OrderID, Line;
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-01-26 : 08:51:51
Another way


SELECT t.*
FROM table t
OUTER APPLY(SELECT COUNT(*) AS Cnt
FROM table
WHERE ORDERID = t.ORDERID
AND OPID = t.OPID
AND QTY = -1 * t.QTY
)t1
WHERE t1.Cnt=0


------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

barnabeck
Posting Yak Master

236 Posts

Posted - 2012-01-26 : 11:01:26
Thank you all three for the help. Now I have to choose... I applied the queries to the proper table and column names and they seem to work fine.
I checked them for some ORDERID's and the results are correct (couldn't verify Ifor's query though). It is not always easy to see where to put the where clause!

Ifor, the query works well but apart from displaying the result it returns an error afterwards:

(59587 row(s) affected)
Msg 208, Level 16, State 1, Line 2
Invalid object name '#t'

I did:

Select * from table #t
;

WITH SQtys
AS
(
SELECT OrderId, Line, Qty, OPID
,SUM(Qty) OVER (PARTITION BY OrderID, OPID) AS SQty
FROM #t
)
SELECT OrderId, Line, Qty, OPID
FROM SQtys
WHERE SQty <> 0
ORDER BY OrderID, Line;

How and where do I insert the WHERE criteria like WHERE OrderID ='PDP34533'?

Regards, Martin
Go to Top of Page

Ifor
Aged Yak Warrior

700 Posts

Posted - 2012-01-26 : 12:01:22
#t is my test table so replace it with your table name.

Your WHERE clause can be changed to:

WHERE SQty <> 0 AND OrderID ='PDP34533'
Go to Top of Page

barnabeck
Posting Yak Master

236 Posts

Posted - 2012-01-26 : 12:37:07
Cool, I actually did use 'myTable' but put the #t behind... and that lead maybe to that error; now it works, although the others queries are notably faster.
Thanks anyway, cheers Martin
Go to Top of Page

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2012-01-26 : 15:11:10
another....

SELECT *
FROM table AS t
WHERE
t1.[QTY] > 0

AND NOT EXISTS (
SELECT 1
FROM table AS t2
WHERE
t2.[orderID] = t1.[OrderID]
AND t2.[QPID] = t1.[QPID]
AND t2.[QTY] < 0
AND t2.[QTY] + t1.[QTY] = 0
)

Don't know about speed but it's a bit more declarative. Can use indexes on orderID, QPID and QTY. Especially a filtered index on QTY might work well.

Edited per visakh suggestion

Charlie
===============================================================
Msg 3903, Level 16, State 1, Line 1736
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-01-26 : 16:26:37
quote:
Originally posted by Transact Charlie

another....

SELECT *
FROM table AS t
WHERE NOT EXISTS (
SELECT 1
FROM table AS t2
WHERE
t2.[orderID] = t1.[OrderID]
AND t2.[QPID] = t1.[QPID]
AND t2.[QTY] < 0
)

Don't know about speed but it's a bit more declarative. Can use indexes on orderID, QPID and QTY. Especially a filtered index on QTY might work well.

Charlie
===============================================================
Msg 3903, Level 16, State 1, Line 1736
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION



this query is not equivalent to earlier suggestions
i think you should also check that absolute values of quantities are same and only sign changes

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2012-01-27 : 03:22:08
good spot -- changed

Charlie
===============================================================
Msg 3903, Level 16, State 1, Line 1736
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-01-27 : 08:27:26
no probs
you're welcome

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

sunitabeck
Master Smack Fu Yak Hacker

5155 Posts

Posted - 2012-01-27 : 08:39:51
Both of you must be seeing something I am not. Although one can infer that OP is looking for matching quantities with opposing signs, in the original posting, the request was "The ommited lines should be double checked by matching both ORDERID AND OPID". Specifically not mentioned was the requirement that QTY should be negative of one another.

Oh well! OP probably solved his/her problem and is thinking about enjoying the weekend, and here we are analyzing it to death.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-01-27 : 08:41:22
quote:
Originally posted by sunitabeck

Both of you must be seeing something I am not. Although one can infer that OP is looking for matching quantities with opposing signs, in the original posting, the request was "The ommited lines should be double checked by matching both ORDERID AND OPID". Specifically not mentioned was the requirement that QTY should be negative of one another.

Oh well! OP probably solved his/her problem and is thinking about enjoying the weekend, and here we are analyzing it to death.


Thats the problem of putting too much thoughts onto anything

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

barnabeck
Posting Yak Master

236 Posts

Posted - 2012-01-30 : 07:58:39
Well, I had a nice weekend and I actually thought this thread to be solved and closed!... actually 4 times solved. Now sunitabeck's last question opens it up to me again and I have to admit I'm a bit confused. I'm still working on that query and everyday I discover new strange ways people add lines in the ERP I have to analyze. I had tested your proposed queries and they worked in this very case, but maybe I was to vague in discribing and they filter stuff I didn't ment to filter without noticing... something that is easy to happen, once you have so many thousands of records.

I have to filter records that had been added in this way: Usually they occur in pairs, but I guess they can be more.
Qty is set to negative number (could be any negative number- although it is not, but in this analysis we don't have to focus on that) and this operation is given a OPID. Any other operation related to this intervention has the same OPID and has to be filtered as well, but only because of its OPID number and not because of number in QTY. Off course all these added records do get the same ORDERID.

Does this change anything?
Martin
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-01-30 : 10:54:48
so are you telling anything with same OPID group but with total qty as 0 should be filtered out?

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

barnabeck
Posting Yak Master

236 Posts

Posted - 2012-01-30 : 12:30:44
I'm not so sure about the way these guys that do enter the numbers actually work. I wont consider the sum being 0 for QTY! This can't be a criteria as I see now. And it is NOT anything with same OPID group, but anything with same OPID AND at least one negative QTY.
so:
1. look for the negative QTY and get its OPID
2. exclude all records with that OPID AND that ORDERID
3. do this for all ORDERID
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-01-30 : 12:35:15
then you need to modify it a bit


SELECT t.*
FROM table t
OUTER APPLY(SELECT COUNT(*) AS Cnt
FROM table
WHERE ORDERID = t.ORDERID
AND OPID = t.OPID
AND QTY < 0
)t1
WHERE t1.Cnt=0


------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

barnabeck
Posting Yak Master

236 Posts

Posted - 2012-01-30 : 12:47:52
Visakh, I don't know if this is correct as it makes me think that you filter only the QTY < 0. This probably doesn't make sense to you either, but it's the way these guys work.
Again (...and I really adore your patience):
1. look for any negative QTY and get the OPID for that record
2. exclude all records with that OPID and that ORDERID regardless their QTY (it only needs one negative QTY to exclude all records with that OPID)
3. do this for all ORDERID
I hope I made it clear... and I said it was tricky ;)
Martin
Go to Top of Page

sunitabeck
Master Smack Fu Yak Hacker

5155 Posts

Posted - 2012-01-30 : 13:33:45
Visakh is really looking for "t1.Cnt=0", and that count being the number of rows for which the QTY is negative. So for a given OPID and ORDERID, if there is at least one row that has a negative QTY, the query will ignore all the rows that have the OPID and ORDERID combination - which, if I understood you correctly, is exactly what you are looking for.

That said, I liked Transact Charlie's query which is:
SELECT *
FROM table AS t
WHERE
NOT EXISTS
(
SELECT 1
FROM table AS t2
WHERE
t2.[orderID] = t1.[OrderID]
AND t2.[QPID] = t1.[QPID]
AND t2.[QTY] < 0
)
But, I know Visakh is the Cross Applying (in this case outer applying) Yak Herder, so I understand his rationale. These outer apply's are somewhat harder for me to wrap my head around.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-01-30 : 13:34:15
quote:
Originally posted by barnabeck

Visakh, I don't know if this is correct as it makes me think that you filter only the QTY < 0. This probably doesn't make sense to you either, but it's the way these guys work.
Again (...and I really adore your patience):
1. look for any negative QTY and get the OPID for that record
2. exclude all records with that OPID and that ORDERID regardless their QTY (it only needs one negative QTY to exclude all records with that OPID)
3. do this for all ORDERID
I hope I made it clear... and I said it was tricky ;)
Martin


thats exactly what i've done
i filter only one which doesnt have a record with QTY <0 attached to it

please check the result and see

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

barnabeck
Posting Yak Master

236 Posts

Posted - 2012-01-30 : 14:45:52
Thank you guys, tomorrow I will check it out. Although I feel much more confident about the query now that I made the point clear what I have to filter. I stick with sunitabeck, as the NOT EXIST comes more close to the way by brain is working. Visakh is THINKING and FEELING in sql, and to me that is far to abstract.
Cheers, Martin
Go to Top of Page
    Next Page

- Advertisement -