简体   繁体   中英

MySQL select names group by alphabet limit to n results per letter

I want to create a query that will get the names from one table then joint it with others, ordered alphabetically for each letter of the alphabet then limit to n results for each letter in one query.

So I don't wan't running 26 queries for each letter like:

SELECT CONCAT_WS(' ',first_name,last_name) AS name FROM encyclopedia WHERE name LIKE "A%" ORDER BY rand() LIMIT 4 
SELECT CONCAT_WS(' ',first_name,last_name) AS name FROM encyclopedia WHERE name LIKE "B%" ORDER BY rand() LIMIT 4 
SELECT CONCAT_WS(' ',first_name,last_name) AS name FROM encyclopedia WHERE name LIKE "C%" ORDER BY rand() LIMIT 4

Right now I have:

SELECT 
      e.id,
      CONCAT_WS(' ',first_name,last_name) AS name,
      sg.name AS sub_name, 
      sg.id AS sub_id 
      FROM ( SELECT id,first_name,last_name FROM encyclopedia ORDER BY RAND() LIMIT 4) AS e
      LEFT JOIN encyclopedia_subgenres esub
      ON ( e.id = esub.enc_id )
      LEFT JOIN subgenres sg
      ON ( esub.subgenre_id = sg.id )
      ORDER BY name

Then from php I create the array from the result:

    Array
(
    [b] => Array
        (
            [2] => Array
                (
                    [name] => B Style
                    [genres] => Array
                        (
                            [26] => Classic
                            [27] => X
                            [29] => Y
                        )

                )

            [7] => Array
                (
                    [name] => Beyonce Giselle Knowles
                    [genres] => Array
                        (
                            [32] => Pop
                        )

                )

        )

    [i] => Array
        (
            [1] => Array
                (
                    [name] => Ivan D
                    [genres] => Array
                        (
                            [27] => R&B
                            [2] => Jazz
                        )

                )

        )

    [m] => Array
        (
            [3] => Array
                (
                    [name] => Maria T
                    [genres] => Array
                        (
                            [26] => Classical
                            [27] => Pop
                            [28] => Dance
                        )

                )

        )

)

But the thing is that it limits me to only 4 random results which can be 4 on the same letter or any combination. Is there a way in doing this ?

Thanks.

I think sql is not that much flexible - but i am not sure. You have to write stored-procedures for that.

First create one that generate this sequence: A, B, C, ..., Z, A, B, C, ..., Z, A, B, C, ... lets call it magic_sequence.

Then create a temporary table having a column, init, seeded from magic sequence, another, count_down, be equal to 4. It should have 26 rows. lets call it init_table;

Then write another function namely acceptance_test that

- take a string S with
- decrease count_down of the corresponding row in init_table
- return true if count_down > = 0; otherwise false

now have a query like that:

SELECT CONCAT_WS(' ',first_name,last_name) AS name FROM encyclopedia WHERE acceptance_test(name) LIMIT 4*26

You also have to randomize if you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM