简体   繁体   中英

SQL: Issue retrieving data via Select query in a specific (static) order

I am currently trying to create a MySQL query, which outputs data from a specific table (images) using a static order. I am currently using UNION ALL to do this, but I'm kinda stuck now.

Here is what I want it to do:

I have a table named images with the following fields: user_id, image, image_dimension (this field values: small, wide, tall, large).

From the images table, I want to retrieve images with specific dimensions in a static order, to fit these into my static image grid. Now it gets complicated: I only want one (1) image per user_id.

This is my try so far:

SELECT
    *
FROM
(

    (SELECT * FROM `artworks` WHERE img = 'Large' LIMIT 1)
    UNION ALL
    (SELECT * FROM `artworks` WHERE img = 'Small' LIMIT 2)
    UNION ALL
    (SELECT * FROM `artworks` WHERE img = 'Large' LIMIT 1)
    UNION ALL
    (SELECT * FROM `artworks` WHERE img = 'Wide' LIMIT 1)
    UNION ALL
    (SELECT * FROM `artworks` WHERE img = 'Small' LIMIT 2)
    UNION ALL
    (SELECT * FROM `artworks` WHERE img = 'Tall' LIMIT 2)
    UNION ALL
    (SELECT * FROM `artworks` WHERE img = 'Large' LIMIT 1)
) AS order

This query pulls images with a specific dimension from the table "images" and with LIMIT - I get the amount I need for the order. This works so far, but it doesn't allow me to only get one image per user_id while keeping the order.

How can I make sure I get the order (see query) but only get one image per user_id?

Order again is: 1x Large, 2x Small, 1x Large, 1x wide, 2x small, 2x tall and 1x large)

Sorry for my bad english, let me know if you need any further description.

Edit:

Table format artworks:
id | user_id | img_name | img

Sample data from artworks:
1  | 1       | Test 1   | Large
2  | 1       | Test 2   | Large
3  | 2       | Test 3   | Small
4  | 2       | Test 4   | Small
5  | 2       | Test 5   | Small
6  | 3       | Test 6   | Small
7  | 3       | Test 7   | Small
8  | 3       | Test 8   | Small
9  | 4       | Test 9   | Large
10 | 4       | Test 10  | Large
11 | 5       | Test 11  | Small
12 | 5       | Test 12  | Wide
13 | 6       | Test 13  | Small
14 | 7       | Test 14  | Small

My expected result (ORDER BY id DESC) to get latest img of each user:

2  | 1       | Test 2   | Large
5  | 2       | Test 5   | Small
8  | 3       | Test 8   | Small
10 | 4       | Test 10  | Large
12 | 5       | Test 12  | Wide
13 | 6       | Test 13  | Small
14 | 7       | Test 14  | Small

One method, which I've yet to test in this circumstance but the idea is correct, would be to construct a helper table in the database containing your image arrangement like so:

----- --------
size  ordering
----- --------
Large 1
Small 2
Small 3
Large 4
Wide  5
Small 6
Small 7
Tall  8
Tall  9
Large 10

Then you'll need to construct a query that will pull out a list of users paired with an ordering number, something like the following:

SET    @ordering = 0;

SELECT artwork.*
FROM   arrangement
JOIN  (SELECT @ordering := @ordering + 1 AS ordering, user_id
       FROM   users) AS ordered_users
       ON arrangement.ordering = ordered_users.ordering
JOIN   artwork ON ordered_users.user_id = artwork.user_id AND
                  arrangement.size = artwork.img
GROUP BY ordering ASC;

The trick here is that the @ordering variable is incremented and set for each row of the users table queried, and this can then be paired with entries form the arrangement table by their ordering number to pair a user, an image size, and their order in the arrangement. Once you've that, you can match them with an image. (Ab)using GROUP BY (rather than ORDER BY ) with some MySQL-specific behaviour eliminates any images of the same size that the user might have, and effectively chooses one of them by some arbitrary method.

This method is far from ideal, especially as it abuses some MySQL-specific behaviour, though that abuse could possibly be eliminated with a correlated subquery. However, it might give you some ideas as to how to solve the problem at the very least.

That said, this kind of thing isn't exactly the sort of thing you'd do with SQL.

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