0

I'm trying to solve task for last hours...

I have four tables:

Users (ID INT, Fullname VARCHAR(255))

Segments (Value VARCHAR(255))

Report_1 (ID INT, UserID INT, Segment VARCHAR(255), Total INT)

Report_2 (ID INT, UserID INT, Segment VARCHAR(255), Total INT)

...and I need to get reports by all users with all possible segments.

But reports from "Report_1", "Report_2" may not have records for some users or segments.

The result query must have this columns:

UserID, Segment, Report_1.Total(OR NULL), Report_2.Total(OR NULL)

Could I use CROSS JOIN / APPLY or something?

2
  • I have edited your title. Please see, "Should questions include “tags” in their titles?", where the consensus is "no, they should not". Commented Mar 19, 2014 at 14:45
  • Now I know it... and absolutely agree! Thanks! Commented Mar 19, 2014 at 14:56

2 Answers 2

3

A simple cartesian join with an outer join should do the trick:

SELECT Users.ID AS [UserID], Segments.Value AS [Segment], Report_1.Total, Report_2.Total
FROM Users, Segments
LEFT OUTER JOIN Report_1 ON 
    Report_1.UserID = Users.ID AND Report_1.Segment = Segments.Value
LEFT OUTER JOIN Report_2 ON 
    Report_2.UserID = Users.ID AND Report_2.Segment = Segments.Value
Sign up to request clarification or add additional context in comments.

1 Comment

I have an error on SQL Server 2012 for real-world query. So I forced to use: FROM Users CROSS JOIN Segments instead of commas...
0

Best that I can suggest is:

SELECT
    U.UserID,
    S.Value,
    ISNULL(R1.Total, 0),
    ISNULL(R2.Total, 0)
FROM
    Users U
CROSS APPLY (
    SELECT DISTINCT Value FROM Segment
) S
LEFT JOIN (
    SELECT
        SUM(Total) AS Total,
        Segment,
        UserID
    FROM
        Report_1
    GROUP BY
        Segment,
        UserID
) R1 ON
    R1.UserID = U.UserID AND
    R1.Segment = S.Value
LEFT JOIN (
        SELECT
        SUM(Total) AS Total,
        Segment,
        UserID
    FROM
        Report_2
    GROUP BY
        Segment,
        UserID
) R2 ON
    R2.UserID = U.UserID AND
    R2.Segment = S.Value

I hope that is good usage for CROSS APPLY...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.