tags:

views:

188

answers:

1

I want to retrieve two columns from the same table, but only if a certain column in the current row isn't set. With just one column to retrieve, there is no problem. Once I need another column, it appears that I need another subquery with another case-clause, but that seems really ineffective. I've never used Joins before, but I'm thinking it's probably really complicated with the case clause?!

I thought the beauty of it was that it actually only executed the (as I heard) wasteful subquery in the few cases when it's needed.

In the docs, I found that comparisons using ROW() are apparently possible. Is there an equivalent for retrieving the columns with AS?

Thank you for any hints, if it only works with Joins, please give me a push in the right direction since they seem kind of complicated and with the case clause it's probably gonna be a mess if I just go ahead.

Ruben

SELECT id, bekannt, (

CASE WHEN bekannt =  ''
    THEN (
        SELECT bekannt
        FROM vokabeln AS v2
        WHERE v2.id = vokabeln.hinweis
        LIMIT 1
    )
    ELSE NULL 
    END
) AS lueckentext, (

CASE WHEN bekannt =  ''
    THEN (
        SELECT hinweis
        FROM vokabeln AS v2
        WHERE v2.id = vokabeln.hinweis
        LIMIT 1
    )
    ELSE NULL 
    END
) AS lthinweis
FROM vokabeln
WHERE nutzer =  'test'
+1  A: 

I'd code it as:

  SELECT
    v1.id, v1.bekannt, v2.bekannt AS lueckentext, v2.hinweis AS lthinweis
  FROM 
    vokabeln AS v1
    LEFT OUTER JOIN vokabeln AS v2
    ON (v1.bekannt='' AND v2.id = v1.hinweis)
  WHERE
    v1.nutzer='test'
Alex Martelli
__Thanks a lot__, this doesn't look as complicated as I expected. I didn't know joins could be conditional. Maybe I'll get it right myself one day.
Ruben
Yep, the `ON` subclause of any `JOIN` clause can be any boolean expression (and the `OUTER` join puts the `NULL`s in place of the second table's fields in the `SELECT` list, if for some row in the first table no row in the second table satisfies the `ON` condition).
Alex Martelli
Can I somehow specify the _default_ table to assume, so I don't have to specify `v1.id`, but `id` will be non-ambigously resolved to `v1.id` (only `v2.something` still specified)?
Ruben
@Ruben, not in portable Sql, though if you're willing to toss out of the window the ability to ever upgrade or port your code in exchange for a microscopic amount of convenience, there might be ways in very specific Sql dialects.
Alex Martelli
Well the convenience wouldn't be exactly microscopic, the query is of course a little larger. But ok, I just thought there might be something like FROM vokabeln AS DEFAULT (well of course something different, but anyway.If I use my two CASE-statements, would I lose a lot? It actually seems worth it, if I look at how the where-clause gets generated…
Ruben
@Ruben, measure the performance with your approach and mine (on data sets large enough to be representative of your actual usage, and on the _real_ query): most likely the `OUTER JOIN` will be substantially faster than the nested queries, but without access to your data set and the actual way you want to set up indices, I can only guess, while you can **measure**.
Alex Martelli
Yes. Thanks for your help and patience! @Alex
Ruben