source

MariaDB 10.3.18 : 랜덤하고 고유한 값을 가진 2개의 레코드를 얻는 방법

manycodes 2022. 10. 26. 21:10
반응형

MariaDB 10.3.18 : 랜덤하고 고유한 값을 가진 2개의 레코드를 얻는 방법

stat이라는 이름의 MySQL 테이블이 있습니다.

line_name  device_name count
1001    3548001  2
1002    3548002  3
1003    3548003  6
2001    3548004  7
2002    3548005  3
2003    3548006  4
3001    3548007  3
3002    3548008  9
3003    3548009  7

첫 번째 문자가 입력된 두 개의 레코드를 선택해야 합니다.line_name는 다릅니다.예를 들어 다음과 같습니다.

1001    3548001  2
3003    3548009  7

또는 다음과 같이 입력합니다.

2002    3548005  3
3001    3548007  3

이거 해봤어요.

SELECT DISTINCT(SUBSTRING(line_name,1,LENGTH(line_name)-3)) as pack_id, device_name, count 
from stat
order by rand()
limit 2;

하지만 가끔 나는 같은 것을 얻는다.pack_id결과 집합에서

MariaDB 10.3에서는ROW_NUMBER() OVER (ORDER BY RAND())각 구별되는 행 번호를 무작위로 생성하다line_name그런 다음 행 번호 = 1인 값의 랜덤 쌍을 선택합니다.

WITH cte AS 
(SELECT *, ROW_NUMBER() OVER (PARTITION BY LEFT(line_name, 1) ORDER BY RAND()) AS rn
 FROM stat)
SELECT `line_name`, `device_name`, `count`
FROM cte
WHERE rn = 1
ORDER BY RAND()
LIMIT 2

dbfiddle 데모

출력(2회 실행의 경우)

line_name   device_name count
1003        3548003     6
3002        3548008     9

line_name   device_name count
2001        3548004     7
1003        3548003     6

MySQL 8.0에서는 CTE에서 테이블을 셀프 조인하여 조건을 충족하는 레코드 쌍을 랜덤하게 찾아 다음 명령을 사용할 수 있습니다.UNION ALL결과를 표시하려면:

WITH cte AS (
    SELECT 
        t1.line_name line_name1,
        t1.device_name device_name1,
        t1.count count1,
        t2.line_name line_name2,
        t2.device_name device_name2,
        t2.count count2
    FROM stat t1
    INNER JOIN stat t2 ON LEFT(t1.line_name, 1) != LEFT(t2.line_name, 1)
    ORDER BY RAND()
    LIMIT 1
)
SELECT line_name1, device_name1, count1 FROM cte
UNION ALL
SELECT line_name2, device_name2, count2 FROM cte

DB Fielen 데모:

실행 #1:

| line_name1 | device_name1 | count1 |
| ---------- | ------------ | ------ |
| 3001       | 3548007      | 3      |
| 2001       | 3548004      | 7      |

실행 #2:

| line_name1 | device_name1 | count1 |
| ---------- | ------------ | ------ |
| 1003       | 3548003      | 6      |
| 2002       | 3548005      | 3      |

넌 할 수 있다.GROUP BY pack_id대응하는 device_name 또는 device_name 중 임의의 것을 선택합니다.ANY_VALUE()MySQL > = 5.7을 사용하는 경우

SELECT 
  SUBSTR(line_name, 1, 1) AS pack_id,
  line_name,
  ANY_VALUE(device_name) AS device_name,
  count
FROM stat
GROUP BY pack_id
ORDER BY RAND()
LIMIT 2

이전 MySQL 버전

SELECT 
  SUBSTR(line_name, 1, 1) AS pack_id,
  line_name,
  device_name,
  count
FROM stat
GROUP BY pack_id
ORDER BY RAND()
LIMIT 2

http://sqlfiddle.com/ #!9/2d466f2/1

pack_id의 계산도 간소화했습니다.

저는 간단하게 다음과 같이 하겠습니다.

select s.*
from stat s
order by row_number() over (partition by left(line_name, 1)
                            order by rand()
                           )
limit 2;

창 기능은 에서 사용할 수 있으므로 하위 쿼리는 필요하지 않습니다.order by.

이것이 가장 효율적인 방법은 아닐 수 있습니다.하지만 테이블이 크지 않으면 공연은 괜찮을 거예요.

언급URL : https://stackoverflow.com/questions/58163041/mariadb-10-3-18-how-to-get-2-records-with-random-and-distinct-value

반응형