Search code examples
phpmysqltemp-tables

how can i get a temp table result from a string?


for example:
my products best sort string is "'8207,17631,16717,18545,9062,17469,17246,17750"

this string is posted from php , I dont want to store them in datebase. I want to query datas from mysql and left join a temp table then sort by the temp table'sort.

how can I get this temp table from a string ?

enter image description here

my codes seems will be like that bellow:(wrong codes)

select
    p.products_id
from
    (
        select '18207,17631,16717,18545,9062,17469,17246,17750' as products_id
    ) as p
order by p.sort

Solution

  • Your best approach could be - to use UNION for generating row set from string. This, however, will require joining your string in your application, like this:

    $string = '18207,17631,16717,18545,9062,17469,17246,17750';
    $id     = 0;
    $sql    = join(' UNION ALL '.PHP_EOL, array_map(function($item) use (&$id)
    {
       return 'SELECT '.(++$id).' AS sort, "'.$item.'" AS products_id';
    }, explode(',', $string)));
    

    -end result will be like:

    SELECT 1 AS sort, "18207" AS products_id UNION ALL 
    SELECT 2 AS sort, "17631" AS products_id UNION ALL 
    SELECT 3 AS sort, "16717" AS products_id UNION ALL 
    SELECT 4 AS sort, "18545" AS products_id UNION ALL 
    SELECT 5 AS sort, "9062" AS products_id UNION ALL 
    SELECT 6 AS sort, "17469" AS products_id UNION ALL 
    SELECT 7 AS sort, "17246" AS products_id UNION ALL 
    SELECT 8 AS sort, "17750" AS products_id
    

    However, if you want to do that in SQL - that will not be easy, since MySQL doesn't supports sequences - and, therefore, you'll need to use some tricks to produce desired rows set. There's a way to generate N consecutive numbers with:

    SELECT id+1
    FROM 
      (SELECT
        (two_1.id + two_2.id + two_4.id + 
        two_8.id + two_16.id) AS id
       FROM
        (SELECT 0 AS id UNION ALL SELECT 1 AS id) AS two_1
        CROSS JOIN (SELECT 0 id UNION ALL SELECT 2 id) AS two_2
        CROSS JOIN (SELECT 0 id UNION ALL SELECT 4 id) AS two_4
        CROSS JOIN (SELECT 0 id UNION ALL SELECT 8 id) AS two_8
        CROSS JOIN (SELECT 0 id UNION ALL SELECT 16 id) AS two_16
       ) AS init
    LIMIT 10
    

    -this will result in 10 numbers 1..10 (check this fiddle). Using this, you can get your end result:

    SELECT 
      ELT(id+1, 18207,17631,16717,18545,9062,17469,17246,17750) AS products_id,
      id+1 AS sort
    FROM 
      (SELECT
        (two_1.id + two_2.id + two_4.id + 
        two_8.id + two_16.id) AS id
       FROM
        (SELECT 0 AS id UNION ALL SELECT 1 AS id) AS two_1
        CROSS JOIN (SELECT 0 id UNION ALL SELECT 2 id) AS two_2
        CROSS JOIN (SELECT 0 id UNION ALL SELECT 4 id) AS two_4
        CROSS JOIN (SELECT 0 id UNION ALL SELECT 8 id) AS two_8
        CROSS JOIN (SELECT 0 id UNION ALL SELECT 16 id) AS two_16
       ) AS init
    HAVING 
      products_id IS NOT NULL
    

    -check this fiddle. However, this may be slow and I recommend you to use your application layer to build desired SQL.