SQL query assistance

ron barlow 411 Reputation points
2022-08-31T15:50:03.957+00:00

Hello

I've got a table of student payments, screen shot (left). What I need is to return a list of students payments that are >0 when a student has one or more payments. or if a student has only one payment entry and the value is 0, return this single row. screen shot (right). I need a least one row for each student

I've tried Union and Partitioning but can't seem to get it to work are required.

236653-q1.png

All suggestions much appreciated

Thanks in advance
Ron

Developer technologies Transact-SQL
{count} votes

Accepted answer
  1. LiHongMSFT-4306 31,566 Reputation points
    2022-09-01T06:24:35.207+00:00

    Hi @ron barlow
    You don't need to use UNION or Partition, just use 'OR' along with subquery in your WHERE filter clause will be fine.
    Please check:

    SELECT * FROM @tbl A  
    WHERE Payment > 0 OR (SELECT COUNT(*) FROM @tbl B WHERE A.StudentID=B.StudentID) = 1  
    

    Also, in this case, you could transfer the logic to: any payment > 0 or Max (payment) =0, like this:

    SELECT * FROM @tbl A  
    WHERE Payment > 0 OR (SELECT MAX(Payment) FROM @tbl B WHERE A.StudentID=B.StudentID) = 0  
    

    Best regards,
    LiHong


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our Documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Yitzhak Khabinsky 26,586 Reputation points
    2022-08-31T17:29:02.28+00:00

    Hi @ron barlow ,

    Please try the following solution.

    SQL

    -- DDL and sample data population, start  
    DECLARE @tbl TABLE (StudentID INT, PolicyID INT, Payment DECIMAL(10,2));  
    INSERT @tbl (StudentID, PolicyID, Payment) VALUES  
    (1, 1000, 100),  
    (1, 1001, 0),  
    (1, 1005, 150),  
    (2, 1009, 0),  
    (3, 1006, 90),  
    (3, 1008, 175),  
    (4, 1007, 110),  
    (4, 1003, 0)  
    -- DDL and sample data population, end  
      
    ;WITH rs AS  
    (  
    	SELECT *   
    		, cnt = COUNT(*) OVER (PARTITION BY StudentID ORDER BY StudentID)  
    	FROM @tbl  
    )  
    SELECT * FROM rs  
    WHERE cnt > 1 AND rs.Payment > 0  
    UNION ALL  
    SELECT * FROM rs  
    WHERE cnt = 1  
    ORDER BY rs.StudentID;  
    

    Output

    +-----------+----------+---------+-----+  
    | StudentID | PolicyID | Payment | cnt |  
    +-----------+----------+---------+-----+  
    |         1 |     1000 |  100.00 |   3 |  
    |         1 |     1005 |  150.00 |   3 |  
    |         2 |     1009 |    0.00 |   1 |  
    |         3 |     1006 |   90.00 |   2 |  
    |         3 |     1008 |  175.00 |   2 |  
    |         4 |     1007 |  110.00 |   2 |  
    +-----------+----------+---------+-----+  
    
    1 person found this answer helpful.
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.