How to convert column values into rows in Sqlite?

后端 未结 1 1799
借酒劲吻你
借酒劲吻你 2020-12-22 01:20

I have a table value in sqlite like..

i\'m getting value in sqlite query like this..

select * from tablename where id=\'101\' and id=\'102\' and id=         


        
1条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-22 01:57

    Oh, so you're stuck with a terrible DB design which you aren't allowed to change... that sucks. It ought to be divided into 4 tables (at least). Anyway, here is one way to do it in this particular case.

    I assume the first query is equivalent to this:

    SELECT id, F1, F2, F3, F4, F5, F6
    FROM tablename
    WHERE id IN (101,102,1,18)
    

    So, you can do transposing/pivoting/whatever it's actually called like this:

    SELECT 
      MAX(CASE WHEN id=101 THEN F1 END) R1,
      MAX(CASE WHEN id=102 THEN F1 END) R2,
      MAX(CASE WHEN id=1 THEN F1 END) R3,
      MAX(CASE WHEN id=18 THEN F1 END) R4
    FROM tablename
    UNION
    SELECT 
      MAX(CASE WHEN id=101 THEN F2 END) R1,
      MAX(CASE WHEN id=102 THEN F2 END) R2,
      MAX(CASE WHEN id=1 THEN F2 END) R3,
      MAX(CASE WHEN id=18 THEN F2 END) R4
    FROM tablename
    UNION
    SELECT 
      MAX(CASE WHEN id=101 THEN F3 END) R1,
      MAX(CASE WHEN id=102 THEN F3 END) R2,
      MAX(CASE WHEN id=1 THEN F3 END) R3,
      MAX(CASE WHEN id=18 THEN F3 END) R4
    FROM tablename
    UNION
    SELECT 
      MAX(CASE WHEN id=101 THEN F4 END) R1,
      MAX(CASE WHEN id=102 THEN F4 END) R2,
      MAX(CASE WHEN id=1 THEN F4 END) R3,
      MAX(CASE WHEN id=18 THEN F4 END) R4
    FROM tablename
    UNION
    SELECT 
      MAX(CASE WHEN id=101 THEN F5 END) R1,
      MAX(CASE WHEN id=102 THEN F5 END) R2,
      MAX(CASE WHEN id=1 THEN F5 END) R3,
      MAX(CASE WHEN id=18 THEN F5 END) R4
    FROM tablename
    UNION
    SELECT 
      MAX(CASE WHEN id=101 THEN F6 END) R1,
      MAX(CASE WHEN id=102 THEN F6 END) R2,
      MAX(CASE WHEN id=1 THEN F6 END) R3,
      MAX(CASE WHEN id=18 THEN F6 END) R4
    FROM tablename
    

    Unfortunately, it's sorted in a strange way.

    And I really advise you to persuade someone in charge to re-design the DB. Some designers think that having tables with such structure is "flexible" and "improves performance", but it's not so: doing actual work with such tables requires highly non-trivial queries, which most of DBMSs cannot optimize because they were never expected to deal with such atrocities.

    Such tables also break the very idea of the relational model. Each table must have one-statement "template", for example, CREATE TABLE S (id INTEGER, name TEXT, address TEXT) can have template "A supplier with id ID is called NAME and is located at ADDRESS". Now, each row in this table yields you a true statement about the world when you put its contents into the template: if S would contain a row (1, "Bob & Co.", "Lime St., 125"), then it would tell you that "A supplier with id 1 is called Bob & Co. and is located at Lime St., 125".

    All relational operations: selection, projection, joins, filtering, etc. don't just combine tables in a particular way, no! They also combine "templates", so you can say what exactly information a query gives you. And vice versa, if you can express what information you want through combining those "templates", it would almost automatically give you a corresponding query.

    And the table you have to work with can be associated with no sane "template". That's why you have to write nonsensical queries in order to get something useful. Note that I can basically guess the "template" of the resulting set,

    R1      R2   R3     R4
    ============================
    Local   9   3:55   4:50
    ...
    

    It's something like "An event of type R2 was happening at place R1, starting at time R3 and ending at time R4". Am I correct?

    0 讨论(0)
提交回复
热议问题