Skip to main content
February 16, 2009
Answered

Almost a month can't get query to work...

  • February 16, 2009
  • 18 replies
  • 3001 views
Help, I can't seem to get this query to work like I need it to. I'm not sure what I'm missing but it all seems fine to me.

Here is what my order table looks like (simlified)
--------------------------------------------------------------------------------------------------------------
id | trait_a | trait_b
--------------------------------------------------------------------------------------------------------------
1 5 6
2 2 1


Here is my materials table (simlified)
---------------------------------------------------------------------------------------------------------------
id | label
---------------------------------------------------------------------------------------------------------------
1 Black
2 Cherry
5 Orange
6 Pink

So for order id 1 it has two traits I need to return Orange and Pink. Order 2 has Cherry and Black for trait a and b. Every way I seem to do this I always just get the second item "b"'s label. I can't get it to return each one. Here's my code. Thanks!
    This topic has been closed for replies.
    Correct answer Kronin555
    Are any of those other fields you're joining on null in your bag_orders table? Namely:
    bag_orders.order_party
    bag_orders.order_consultant
    bag_orders.order_hostess
    bag_orders.order_customer
    bag_orders.bag_style
    bag_orders.bag_trait_a
    bag_orders.bag_trait_b
    ?
    If any of those fields you're doing an inner join on are null, or don't have matching records in the tables you're joining to, the query won't return any rows.

    Also, to simplify, it looks like arguments.thisParty is always going to be a single integer. You can remove the IN check and just do an equality check:
    WHERE bag_orders.order_party = <cfqueryparam value="#arguments.thisParty#" cfsqltype="cf_sql_integer">

    18 replies

    Participating Frequently
    February 17, 2009
    You're welcome. Glad it's all working now :-)
    February 17, 2009
    Ah ha! you were correct sir! There wasn't a material with the id of 1. There used to be and somehow I removed it. Thanks! I really really appreciate it. This has taken forever to fix! :)
    Kronin555Correct answer
    Participating Frequently
    February 17, 2009
    Are any of those other fields you're joining on null in your bag_orders table? Namely:
    bag_orders.order_party
    bag_orders.order_consultant
    bag_orders.order_hostess
    bag_orders.order_customer
    bag_orders.bag_style
    bag_orders.bag_trait_a
    bag_orders.bag_trait_b
    ?
    If any of those fields you're doing an inner join on are null, or don't have matching records in the tables you're joining to, the query won't return any rows.

    Also, to simplify, it looks like arguments.thisParty is always going to be a single integer. You can remove the IN check and just do an equality check:
    WHERE bag_orders.order_party = <cfqueryparam value="#arguments.thisParty#" cfsqltype="cf_sql_integer">
    Participating Frequently
    February 17, 2009
    I just tested it again.

    select * from bag_orders;
    order_id | bag_trait_a | bag_trait_b | order_party
    ----------+-------------+-------------+-------------
    1 | 1 | 2 | 1
    2 | 2 | 3 | 1
    3 | 1 | 3 | 2

    material_id | material_label
    -------------+----------------
    1 | Leather
    2 | Suede
    3 | Velour

    select bag_orders.order_id, materials_a.material_label as bag_trait_a, materials_b.material_label as bag_trait_b from bag_orders join materials as materials_a on (bag_orders.bag_trait_a = materials_a.material_id) join materials as materials_b on (bag_orders.bag_trait_b = materials_b.material_id) where order_party in (1);
    order_id | bag_trait_a | bag_trait_b
    ----------+-------------+-------------
    1 | Leather | Suede
    2 | Suede | Velour

    select bag_orders.order_id, materials_a.material_label as bag_trait_a, materials_b.material_label as bag_trait_b from bag_orders join materials as materials_a on (bag_orders.bag_trait_a = materials_a.material_id) join materials as materials_b on (bag_orders.bag_trait_b = materials_b.material_id) where order_party in (2);
    order_id | bag_trait_a | bag_trait_b
    ----------+-------------+-------------
    3 | Leather | Velour

    What is your query now?
    February 17, 2009
    Is it possible I'm missing something set up correctly with the database?

    Here is what I have:

    SELECT
    bag_orders.order_id AS order_id,
    parties.party_name AS party_name,
    consultants.consultant_name AS party_consultant,
    hostesses.hostess_name AS party_hostess,
    customers.customer_name AS customer_name,
    bag_styles.style_name AS style_name,
    materials_a.material_label AS bag_trait_a,
    materials_b.material_label AS bag_trait_b


    FROM bag_orders
    INNER JOIN parties ON bag_orders.order_party=parties.party_id
    INNER JOIN consultants ON bag_orders.order_consultant=consultants.consultant_id
    INNER JOIN hostesses ON bag_orders.order_hostess=hostesses.hostess_id
    INNER JOIN customers ON bag_orders.order_customer=customers.customer_id
    INNER JOIN bag_styles ON bag_orders.bag_style=bag_styles.style_id
    INNER JOIN materials as materials_a ON bag_orders.bag_trait_a=materials_a.material_id
    INNER JOIN materials as materials_b ON bag_orders.bag_trait_b=materials_b.material_id

    WHERE bag_orders.order_party IN(<cfqueryParam value="#arguments.thisParty#" cfsqltype="cf_sql_integer">)
    Participating Frequently
    February 17, 2009
    I'll ask again. If you write a simple Coldfusion page that does nothing more than call this function with an order_party of 1, then <cfdump var="#result#">, what is the result?
    If that works, your problem is in your client code, not this query.
    February 17, 2009
    Kronin, I'm not getting the right result in mySQL, in the query area so the CF result wouldn't be any different.

    bag_orders.order_id,
    materials_a.material_label as traitA,
    materials_b.material_label as traitB

    from bag_orders
    join materials as materials_a on (bag_orders.bag_trait_a = materials_a.material_id)
    join materials as materials_b on (bag_orders.bag_trait_b = materials_b.material_id)


    If I use this code above it only returns the third order_id item. If I add this statement:
    WHERE bag_orders.order_party IN(2) // this works fine as well because there is only one result.
    WHERE bag_orders.order_party IN(1) // this is empty, no results.

    Still inside mySQL query browser if I take the full amount of code, from the SS and I run the query I get the same results. However removing the b traits from the query it returns 2 items and if I remove a and b traits it returns all 3 items. This means that giving the alias to the materials isn't working for a result set of more than 1. Make sense?

    By doing everything in mySQL query browser I can eliminate any other code problems. It's just not working correctly there.
    February 17, 2009
    I got that to work on order_party 2 but it doesn't work on order_party 1 because there are more than one bag_orders it must return. What am I missing?

    Looking at the bag_orders screen shot:
    If the requested party query is 1 then it should return order_id 1 and 2 with all of the items for each order. Instead the query returns and empty set.

    Is there something else I'm missing?
    Participating Frequently
    February 17, 2009
    Well, running that function with an order_party of 1 will return a query with 2 rows. In order to determine why your client isn't displaying those rows, we'll have to see the code in your client where you're calling this function.

    If you call this function with a test ColdFusion page, passing it a order_party of 1, and cfdump the resulting query return value, I'd bet it comes back just fine (2 rows, one for each order_id). If not, if you've changed the query from what's in the screenshot, post that.
    Inspiring
    February 17, 2009
    MySQL allows "intuitive/intelligent" grouping:
    you do not need to specify ALL non-aggregate columns in the GROUP BY
    clause, just need one column

    i like this MySQL feature very much... but sometimes it throws all your
    carefully created table indexes away and runs with a full table scan
    instead... so on small tables it is fine, but on large ones it may cause
    a serious performance problem...

    Azadi Saryev
    Sabai-dee.com
    http://www.sabai-dee.com/
    Participating Frequently
    February 17, 2009
    OK, Carey. I made a simplified version of your table structure and ran a simplified version of the query I posted. It works.

    select * from bag_orders;
    order_id | bag_trait_a | bag_trait_b
    ----------+-------------+-------------
    1 | 1 | 2
    2 | 2 | 3
    3 | 1 | 3

    select * from materials;
    material_id | material_label
    -------------+----------------
    1 | Leather
    2 | Suede
    3 | Velour

    select bag_orders.order_id, materials_a.material_label as bag_trait_a, materials_b.material_label as bag_trait_b from bag_orders join materials as materials_a on (bag_orders.bag_trait_a = materials_a.material_id) join materials as materials_b on (bag_orders.bag_trait_b = materials_b.material_id);
    order_id | bag_trait_a | bag_trait_b
    ----------+-------------+-------------
    1 | Leather | Suede
    3 | Leather | Velour
    2 | Suede | Velour

    Trying to run the query you posted in your screenshot, and my query I posted earlier, throws an error (in a proper database) because you're also doing a "group by bag_orders.order_id". Take that out, and it should work. I don't know why MySQL would actually return something rather than throwing an error...

    Sorry I missed the "group by" clause earlier
    February 17, 2009
    When I ran this code on my existing database it didn't return all three order id's from the database, just the third? Why?
    February 17, 2009
    It's empty, just tried it again. It should bring the two rows back but doesn't. If the party value is 2 I get the one row, which is correct, but when party value is 1 I get no results.
    Inspiring
    February 17, 2009
    normalize your db as Kronin555 has suggested.

    Azadi Saryev
    Sabai-dee.com
    http://www.sabai-dee.com/
    February 17, 2009
    Kronin, Your post two up with the select statement changed doesn't work either, it still only brings back trait_a and does it twice, for a and b. I actually tried it when it didn't work before my last post. Then tried it again and it still doesn't work either.

    Participating Frequently
    February 17, 2009
    quote:

    Originally posted by: C-Rock
    Kronin, Your post two up with the select statement changed doesn't work either, it still only brings back trait_a and does it twice, for a and b. I actually tried it when it didn't work before my last post. Then tried it again and it still doesn't work either.



    Let me break it down for you:
    <cfquery name="getAllPartyBagsQuery" datasource="******" username="******" password="******">
    SELECT
    bag_orders.order_id AS order_id,
    parties.party_name AS party_name,
    consultants.consultant_name AS party_consultant,
    hostesses.hostess_name AS party_hostess,
    customers.customer_name AS customer_name,
    bag_styles.style_name AS style_name,
    materials_a.material_label AS bag_trait_a,
    materials_b.material_label AS bag_trait_b
    FROM bag_orders INNER JOIN parties ON bag_orders.order_party=parties.party_id
    INNER JOIN consultants ON bag_orders.order_consultant=consultants.consultant_id
    INNER JOIN hostesses ON bag_orders.order_hostess=hostesses.hostess_id
    INNER JOIN customers ON bag_orders.order_customer=customers.customer_id
    INNER JOIN bag_styles ON bag_orders.bag_style=bag_styles.style_id
    INNER JOIN materials as materials_a ON bag_orders.bag_trait_a=materials_a.material_id
    INNER JOIN materials as materials_b ON bag_orders.bag_trait_b=materials_b.material_id
    WHERE bag_orders.order_party IN(<cfqueryParam value="#arguments.thisParty#" cfsqltype="cf_sql_integer">)
    GROUP BY bag_orders.order_id
    </cfquery>

    These lines:
    materials_a.material_label AS bag_trait_a,
    materials_b.material_label AS bag_trait_b
    select the label from the materials table that corresponds to these join statements (note the use of "materials_a" and "materials_b" instead of "materials". These are aliases):
    INNER JOIN materials as materials_a ON bag_orders.bag_trait_a=materials_a.material_id
    INNER JOIN materials as materials_b ON bag_orders.bag_trait_b=materials_b.material_id

    Essentially, what this does is join your query to 2 copies of the Materials table. One of those copies, we're calling "materials_a" and joining on bag_trait_a, the other one we're calling "materials_b" and joining on bag_trait_b. Nowhere in your query should you be referencing "materials" directly, you reference using the alias names.

    Post the exact query you're using now, along with what output you're getting and the output you're expecting to get. Double-check and make sure that the values stored in trait_a and trait_b in your orders table aren't identical. It sounds like, with what you say about the mapping table and it being confusing and how you have traits from a to g, that this query you're posting isn't exactly like what you're running that isn't working. It makes it very difficult to help you. Please post exactly what you're running, and I'll fix it for you.

    Regarding the mapping table, you can do it how you want. Mapping tables are how most developers that know what they're doing will do it. It simplifies things and makes tasks like what you're trying to do here much easier.
    February 17, 2009
    I have some screen shots. I commented out the other items that don't have any affect on the result focusing on just the traits to make it easier. Also focus on the bag_orders order_id number 3. There's only one bag in this party order. Basically a party number is passed to the coldfusion query. In the example I'm focusing on the party passed is "2". So bag trait_a 5003 and b is 7035.

    The output I'm getting when tracing in flash the result query trait_a and trait_b always turn out to bethe label in this case for material_id 5003 which is Black Cherry Heather.



    SS1

    SS2

    Thanks