Ineffecient query - Is there a better way?

Ask a Question related to Coldfusion Database Access, Design and Development.

  1. #1

    Default Ineffecient query - Is there a better way?

    I'm trying to determine how many distinct "members" have paid in either one of
    two tables. In the table 'confirm_tourns', the field 'tourn_paid' will = 1 for
    paid. In the table 'confirm_lessons', the field 'lesson_paid' will = 1 for
    paid. I'm using the member_id from a members tables, where each member_id is
    unique.

    Here are the two pieces of code that I have tried. Both either take forever
    and nearly grind my computer to a halt, or else timeout. I'm thinking there
    must be a more efficient way to write this, but am not an expert in MySQL.

    Thanks

    <--- FIRST ATTEMPT --->
    SELECT COUNT(DISTINCT members.member_id ) AS total_members
    FROM members, confirm_lessons, confirm_tourns
    WHERE (members.member_id = confirm_lessons.member_id AND lesson_paid =1)
    OR (members.member_id = confirm_tourns.member_id AND tourn_paid =1)

    <--- SECOND ATTEMPT --->


    <cfquery name="get_paid_members" datasource="dbtcjga" username="tcjga"
    password="uin2tcjga">
    SELECT member_id
    FROM members
    WHERE app_status="confirmed"
    </cfquery>

    <cfset partIcipating_members=0>

    <cfoutput query="get_paid_members">
    <cfquery name="count_part_members" datasource="dbtcjga" username="tcjga"
    password="uin2tcjga">
    SELECT COUNT(DISTINCT members.member_id ) AS part_members
    FROM members, confirm_lessons, confirm_tourns
    WHERE members.member_id=#member_id#
    AND(members.member_id = confirm_lessons.member_id AND
    lesson_paid =1)
    OR (members.member_id = confirm_tourns.member_id AND
    tourn_paid =1)
    </cfquery>

    <cfif count_paid_members.part_member GT 0>
    <cfset participating_members = participating_members + 1>
    </cfif>

    </cfoutput>

    <cfoutput query="count_part_members">
    #part_members#</cfoutput>

    Bagger Vance Guest

  2. Similar Questions and Discussions

    1. Query of Query to select a title first letter
      The column "title" exists in a normal query. Need to select the first letter of the titles to build a list for a prev-next alphabetical search. ...
    2. Query of Queries on query New type query
      In CF5 we have a page that creates a query, using queryNew and querySetCell and the like, we then used dbtype="query" and gave it's name so we could...
    3. Convert a query to a list, or find an item in a query
      Hi All, I am using CFPOP to retrieve mail from a server, then delete each message after I retrieve it. What I want to do is to check that I don;t...
    4. CAML Query: Multiple Query Fields Issue
      I need to Create a CAML Query Dynamically with VB to a Sharepoint WebService GetListItems Method. The User Could Select 1 to X Number of IDs...
    5. BCP query out executed by xp_cmdshell works fine from query analyzer but fails from VB Component
      Hi all, I have a stored procedure which returns a vast number of record and i have to write the output into a csv file. I'm using BCP utility to...
  3. #2

    Default Re: Ineffecient query - Is there a better way?

    the first way is the way to do it, but you can clean it up a bit. Also, you
    need to make sure you have indexes on the 3 tables as follows:
    Unique index on Members.member_id
    Index on confirm_lessons.member_id
    Index on confirm_tourns.member_id

    SELECT COUNT(members.member_id) AS total_members
    FROM members LEFT JOIN confirm_lessons ON (members.member_id =
    confirm_lessons.member_id)
    LEFT JOIN confirm_tourns ON (members.member_id = confirm_tourns.member_id)
    WHERE lesson_paid = 1 and tourn_paid = 1
    GROUP BY members.member_id

    Kronin555 Guest

  4. #3

    Default Re: Ineffecient query - Is there a better way?

    Always more than one way to do something.

    select distinct member_id
    from confirm_lessons
    union
    select distinct member_id
    from confirm_tourns

    Your answer will be the recordcount.

    If your db supports subqueries in the where clause, do this
    select count(member_id) as myanswer
    from
    (select distinct member_id
    from confirm_lessons
    union
    select distinct member_id
    from confirm_tourns ) x



    Dan Bracuk Guest

  5. #4

    Default Re: Ineffecient query - Is there a better way?

    Sorry to be so tardy in my response, but I got pulled away by other projects.

    I don't know if I understand the indexes. Members.member_id is the primary
    key, so I think that means it already has a unique index. I added indexes for
    the other two that you mentioned, but didn't select unique or full text which
    seemed to be the two options available. Hopefully that is correct.

    When I ran your query, it returned multiple rows of "total_members". Perhaps
    if they were totalled they would be the correct number?

    I appreciate your response. Any additional help would be welcome.

    Thanks


    Originally posted by: Kronin555
    the first way is the way to do it, but you can clean it up a bit. Also, you
    need to make sure you have indexes on the 3 tables as follows:
    Unique index on Members.member_id
    Index on confirm_lessons.member_id
    Index on confirm_tourns.member_id

    SELECT COUNT(members.member_id) AS total_members
    FROM members LEFT JOIN confirm_lessons ON (members.member_id =
    confirm_lessons.member_id)
    LEFT JOIN confirm_tourns ON (members.member_id = confirm_tourns.member_id)
    WHERE lesson_paid = 1 and tourn_paid = 1
    GROUP BY members.member_id



    Bagger Vance Guest

  6. #5

    Default Re: Ineffecient query - Is there a better way?

    Thanks for your suggestion.

    The result from your query comes up with a list of member_id's, not a record
    count as far as I can tell. I tried your second query, but it produced an
    error. I am using mySQL.

    Bagger




    \Originally posted by: Dan Bracuk
    Always more than one way to do something.

    select distinct member_id
    from confirm_lessons
    where lessons_paid = 1
    union
    select distinct member_id
    from confirm_tourns
    where tourns_paid = 1
    Your answer will be the recordcount.

    If your db supports subqueries in the where clause, do this
    select count(member_id) as myanswer
    from
    (select distinct member_id
    from confirm_lessons
    where lessons_paid = 1
    union
    select distinct member_id
    from confirm_tourns
    where tourn_paid = 1) x





    Bagger Vance Guest

  7. #6

    Default Re: Ineffecient query - Is there a better way?

    Originally posted by: Bagger Vance
    Thanks for your suggestion.

    The result from your query comes up with a list of member_id's, not a record
    count as far as I can tell. I tried your second query, but it produced an
    error. I am using mySQL.

    Bagger


    Recordcount is one of three variables that are available with cfquery. The
    other two are currentrow and columnlist. Details are in the cfml reference
    manual. If you don't have one, the internet does.

    By the way, you had the answer.

    Dan Bracuk Guest

  8. #7

    Default Re: Ineffecient query - Is there a better way?

    When posing problems, please mention what version of MySQL you are using --
    your best options vary wildly as MySQL adds features.

    Anyway, Kronin's query looked close. Try this:

    SELECT COUNT (members.member_id) AS total_members
    FROM members
    LEFT JOIN confirm_lessons ON (members.member_id = confirm_lessons.member_id)
    LEFT JOIN confirm_tourns ON (members.member_id = confirm_tourns.member_id)
    WHERE lesson_paid = 1
    OR tourn_paid = 1


    MikerRoo Guest

  9. #8

    Default Re: Ineffecient query - Is there a better way?

    Ah ha! Thanks for the explanation Dan. The query does work significantly faster
    than what I was using. The only odd thing is that my 1st Attempt query gives a
    total_members count of one less than the recordcount of yours. There is
    probably another simple explanation for this, but I'm not sure what it is.

    Thanks again for your help. -Bagger

    Originally posted by: Dan Bracuk
    Originally posted by: Bagger Vance
    Thanks for your suggestion.

    The result from your query comes up with a list of member_id's, not a record
    count as far as I can tell. I tried your second query, but it produced an
    error. I am using mySQL.

    Bagger


    Recordcount is one of three variables that are available with cfquery. The
    other two are currentrow and columnlist. Details are in the cfml reference
    manual. If you don't have one, the internet does.

    By the way, you had the answer.

    significantly

    Bagger Vance Guest

  10. #9

    Default Re: Ineffecient query - Is there a better way?

    Something must be off on this one... This result of total_members from the
    query below was 1982 when it should be 427.

    Thanks for your help. This is a great learning experience seeing the different
    approaches to the same problem.

    Originally posted by: MikerRoo
    When posing problems, please mention what version of MySQL you are using --
    your best options vary wildly as MySQL adds features.

    Anyway, Kronin's query looked close. Try this:

    SELECT COUNT (members.member_id) AS total_members
    FROM members
    LEFT JOIN confirm_lessons ON (members.member_id = confirm_lessons.member_id)
    LEFT JOIN confirm_tourns ON (members.member_id = confirm_tourns.member_id)
    WHERE lesson_paid = 1
    OR tourn_paid = 1




    Bagger Vance Guest

  11. #10

    Default Re: Ineffecient query - Is there a better way?

    Bagger,

    Sorry about the faulty query. I shouldn't have had the GROUP BY in there.
    Also, I was using AND, where there should have been an OR. Nice corrections,
    MikerRoo.

    The reason you're getting more than you expect is because each member_id is
    being counted for each lesson or tourn they've paid for.

    Try adding a DISTINCT into your COUNT, like so:

    SELECT COUNT (DISTINCT(members.member_id)) AS total_members
    FROM members
    LEFT JOIN confirm_lessons ON (members.member_id = confirm_lessons.member_id)
    LEFT JOIN confirm_tourns ON (members.member_id = confirm_tourns.member_id)
    WHERE lesson_paid = 1
    OR tourn_paid = 1


    Kronin555 Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139