Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

SQL join

Status
Not open for further replies.

DirtyHairy

Programmer
Joined
Oct 18, 2006
Messages
2
Location
US
Hello,

I am trying to run this on SQL Server 2000. I have 5 tables set up with these fields, in addition to others:

[tt]table ug
--------
ugid


table u
-------
uid
fname
lname


table s
-------
uid
cid
total_score
completed
counter


table uga
---------
ugid
uid


table ugl
---------
ugid
uid[/tt]



What I need in the recordset is ug.ugid, u.uid, u.fname, u.lname, s.total_score, s.completed, s.counter, a field indicating if the ugid/uid combo is in the uga table, and a field indicating if the ugid/uid combo is in the ugl table. The constraints are that I need the entire list of ugids (possibly indicating an outer join), and the s.cid will be a constant for all rows (where s.cid='cid'). I also need the recordset ordered by ugid. There might be more then one row for each ugid, so it will need to be ordered by ugid. The only rows I need returned are ones where the ugid/uid combo appears in either the uga or ugl table, and I also need to know which it appears in.

I can do this with 2 queries, I can get the list of ugids first and then the information for each one, but with the size of the data I am working with, that report takes around 30 minutes to complete. So, it's not exactly the best choice.

Does anyone know how to get all of the information with 1 query, or would it be better to rethink the way the database is set up in the first place? There are certain constraints on the database that make a complete redesign impossible, but I would probably be able to redo the way I am storing the ugl information.

Right now this is how I have the code set up, which is written in ASP/VBscript:

Code:
ugcon.open("SELECT ugid FROM usergroups ORDER BY ugid ASC")

...

  for i = LBound(uglist) to UBound(uglist)
    if ereg(uglist(i), "[A-Z]{2}[0-9]{3}", true) = true then 

      s = "SELECT u.uid, u.fname, u.lname, s.total_score, s.completed, s.counter, 'Y' AS ugadmin FROM "
      s = s & "(users u LEFT OUTER JOIN content_session s ON "
      s = s & "u.uid=s.uid AND s.cid='BOB-MAN') "
      s = s & "WHERE u.uid IN (SELECT uid FROM usergroup_admins WHERE ugid='" & uglist(i) & "') "
      s = s & "UNION "
      s = s & "SELECT u.uid, u.fname, u.lname, s.total_score, s.completed, s.counter, ' ' AS ugadmin FROM "
      s = s & "(users u LEFT OUTER JOIN content_session s ON "
      s = s & "u.uid=s.uid AND s.cid='BOB-MAN') "
      s = s & "WHERE u.uid NOT IN (SELECT uid FROM usergroup_admins WHERE ugid='" & uglist(i) & "') AND u.uid IN (SELECT uid FROM user_grouplist WHERE ugid='" & uglist(i) & "')"

      usercon.open(s)

...

Obviously, having the query inside the loop is destroying efficiency.
 
This should be close:

SELECT
...
CASE WHEN uga.ugid IS NOT NULL THEN 'Y' ELSE 'N' END,
CASE WHEN ugl.ugid IS NOT NULL THEN 'Y' ELSE 'N' END
FROM ug LEFT JOIN u ON ...
(LEFT?) JOIN s ON ...
LEFT JOIN uga ON ug.ugid = ugl.ugid AND u.uid = uga.uid
LEFT JOIN ugl ON ug.ugid = ugl.ugid AND u.uid = ugl.uid
WHERE ...

Dieter
 
Thanks for the reply. After staring at it for a while I actually just built some temporary tables and used a series of simple queries to put the data into a table, and then selected everything from that final table to display. The report time is now about 11 seconds, 4 or 5 of which are the queries, so it's manageable now.

DELETE FROM report_bob_table1

INSERT INTO report_bob_table1 SELECT ugid, uid, ' ' AS ugadmin FROM user_grouplist

DELETE FROM report_bob_table1 WHERE EXISTS
(SELECT * FROM usergroup_admins WHERE usergroup_admins.uid=report_bob_table1.uid AND usergroup_admins.ugid=report_bob_table1.ugid)

INSERT INTO report_bob_table1 SELECT ugid, uid, 'Y' AS ugadmin FROM usergroup_admins

DELETE FROM report_bob_table2

INSERT INTO report_bob_table2
SELECT r.ugid, r.uid, r.ugadmin, u.fname, u.lname, s.total_score, s.completed, s.counter
FROM report_bob_table1 AS r
INNER JOIN users AS u ON r.uid=u.uid
LEFT OUTER JOIN content_session AS s ON s.uid=r.uid AND s.cid='BOB-MAN'

INSERT INTO report_bob_table2 SELECT ugid, null, null, null, null, null, null, null FROM usergroups WHERE ugid NOT IN (SELECT ugid FROM report_bob_table2)

SELECT * FROM report_bob_table2 ORDER BY ugid, uid
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top