IT

MySQL - 표의 id 필드에 상대가 없는 숫자 목록에서 선택

itgroup 2023. 10. 20. 13:34
반응형

MySQL - 표의 id 필드에 상대가 없는 숫자 목록에서 선택

숫자 목록이 있어요, 예를 들어 {2,4,5,6,7} 테이블, 푸스, 푸스가 있어요.{1,2,3,4,8,9}과 같은 ID

제 번호 목록을 가져가서 제 표의 ID 필드에서 상대방이 없는 번호를 찾고 싶습니다.

이를 달성하기 위한 한 가지 방법은 ID 필드에 {2,4,5,6,7}이(가) 로드된 테이블 막대를 만드는 것입니다.그러면 저는.

막대를 선택합니다.* 막대 왼쪽에서 막대에 결합 푸스를 연결합니다.= 똥.똥 싸는 곳.ID가 NULL입니다.

하지만 저는 이 산스 템프 테이블을 달성하고 싶습니다.

그것이 어떻게 일어날지에 대한 의견이 있는 사람?

이 문제는 매우 일반적인 문제입니다. 표를 만들지 않고 바로 관계를 생성하는 것입니다.이 문제에 대한 SQL 솔루션은 상당히 어색합니다.파생된 표를 사용한 한 가지 예:

SELECT n.id
FROM
  (SELECT 2 AS id 
   UNION SELECT 3 
   UNION SELECT 4 
   UNION SELECT 5 
   UNION SELECT 6 
   UNION SELECT 7) AS n
  LEFT OUTER JOIN foos USING (id)
WHERE foos.id IS NULL;

그러나 6개가 아니라 많은 값을 가질 수 있기 때문에 이는 확장성이 좋지 않습니다.하나로 긴 리스트를 구성하는 것은 귀찮을 수 있습니다.UNION값 당 필요한.

또 다른 해결책은 범용 테이블인 10자리를 항상 곁에 두고 여러 용도로 반복적으로 사용하는 것입니다.

CREATE TABLE num (i int);
INSERT INTO num (i) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);

SELECT n.id
FROM 
  (SELECT n1.i + n10.i*10 AS id
   FROM num AS n1 CROSS JOIN num AS n10
   WHERE n1.i + n10.i*10 IN (2, 3, 4, 5, 6, 7)) AS n
  LEFT OUTER JOIN foos USING (id)
WHERE foos.id IS NULL;

0에서 값을 생성하는 내부 쿼리를 보여 줍니다.99 이것이 이 사건에 필요하지는 않지만요.그러나 목록에서 10보다 큰 값을 가질 수도 있습니다.중요한 것은 한 테이블로num, 당신은 하나로 매우 긴 체인에 의존할 필요 없이 큰 숫자를 생성할 수 있습니다.UNION마다을 한할 수 있어 읽을 수 있습니다.또한 원하는 값의 목록을 한 곳에서 지정할 수 있어 더욱 편리하고 읽을 수 있습니다.

임시 테이블을 사용하지 않는 정확한 문제에 대한 해결책을 찾을 수는 없지만, 조인 대신 하위 선택을 사용하여 쿼리를 수행하는 다른 방법은 다음과 같습니다.

SELECT bars.* FROM bars WHERE bars.ID NOT IN (SELECT ID FROM foos)

제가 처음에 썼던 다른 포스터들처럼 말이죠.

SELECT * FROM foos WHERE foos.ID NOT IN (2, 4, 5, 6, 7)

당신이 원하는 것과는 정반대의 결과를 만들어내고 있다는 걸 깨달았어요

PHP를 사용하면 임시 테이블을 만들지 않고도 이 작업을 할 수 있습니다.

SELECT ID FROM foos WHERE foos.ID IN (2, 4, 5, 6, 7)

PHP의 array_diff() 함수를 이용하여 원하는 결과로 변환할 수 있습니다.만약 당신의 리스트(2,4,5,6,7)가 $list라고 불리는 배열에 있고 위의 쿼리의 결과가 배열 $result에 있다면,

$no_counterparts = array_diff($list, $result);

...데이터베이스 테이블에 상대방이 없고 목록에 있는 모든 번호를 반환합니다.이 솔루션이 쿼리 내에서 전체 작업을 수행하는 것은 아니지만 PHP에서 수행해야 하는 후처리는 원하는 작업을 수행하기에 최소한이며 임시 테이블을 생성할 필요가 없도록 하는 것이 가치가 있을 수 있습니다.

저도 비슷한 문제가 있었습니다.자동 증가 기본 키에 누락된 값이 있는 범위가 있어서 먼저 몇 개인지 알아냈습니다.select count(*) from node where nid > 1962. 이 숫자를 가장 높은 값과 비교해보니 누락된 숫자가 있습니다.그런 다음 쿼리를 실행했습니다.select n2.nid from node n1 right join node n2 on n1.nid = (n2.nid - 1) where n1.nid is null and n2.nid > 1962이렇게 하면 연속적이지 않은 누락 레코드 수를 알 수 있습니다.연속된 것은 표시되지 않으며, ON 절을 위도가 더 높을 수 있도록 변경하는 것 외에 어떻게 해야 할지 완전히 확신할 수 없습니다(JOIN 테이블이 상당히 커짐).어쨌든 이로써 총 7명의 실종자 중 5명의 결과가 나왔고, 나머지 2명은 5명 중 적어도 1명 다음으로 보장되었습니다.더 큰 숫자의 실종자가 있다면 남은 실종자를 찾을 다른 방법이 필요할 것입니다.

Alnitak의 (그리고 당신의) 솔루션은 효과가 있을 것이고, SQL 언어로만 작동할 수 있는 다른 것에 대해서는 저는 아무것도 할 수 없습니다.

그러나 여기서 질문이 나옵니다. 가치의 목록을 어떻게 통과하느냐는 것입니다.이런 종류의 조작에 더 적합한 언어로 사용될 수 있는, 즉 ID를 요청하고 콜링 코드에서 비교하는 것이 더 낫지 않습니까?

답을 찾다가 우연히 이곳에 도착했습니다.이전 게시물은 MySQL 8 이전 게시물입니다. MySQL은value버전 8.0.19 이후로 질문은 매우 우아하게 해결될 수 있습니다.value성명서와 함께CTEMySQL 8.0 이후에도 사용 가능합니다.

1단계: CTE와 value statement를 결합하여 표와 비교할 필요가 있는 값으로 행 집합을 만듭니다(여기서 표는foo).

with MyValues(val) as
(
  values row(2),row(4),row(5),row(6),row(7)
)

2단계: 외부에서 테이블과 함께 CTE를 결합합니다.foo외부 조인 후 CTE에서 null 값을 가지는 행을 필터링합니다.foo

WITH myvalues(val)
     AS (VALUES ROW(2), ROW(4), ROW(5), ROW(6), ROW(7))
SELECT f.id
FROM   foo f
       LEFT OUTER JOIN myvalues m
                    ON f.id = m.val
WHERE  m.val IS NULL; 

자국

mysql> WITH myvalues(val)
    ->      AS (VALUES ROW(2), ROW(4), ROW(5), ROW(6), ROW(7))
    -> SELECT f.id
    -> FROM   foo f
    ->        LEFT OUTER JOIN myvalues m
    ->                     ON f.id = m.val
    -> WHERE  m.val IS NULL;
+------+
| id   |
+------+
|    1 |
|    3 |
|    8 |
|    9 |
+------+
4 rows in set (0.00 sec)

또는 IN 절을 사용합니다.

mysql> WITH myvalues(val)
    ->      AS (VALUES ROW(2), ROW(4), ROW(5), ROW(6), ROW(7))
    -> SELECT f.id
    -> FROM   foo f
    -> WHERE  id NOT IN (SELECT val
    ->                   FROM   myvalues);
+------+
| id   |
+------+
|    1 |
|    3 |
|    8 |
|    9 |
+------+
4 rows in set (0.00 sec)

언급URL : https://stackoverflow.com/questions/273623/mysql-select-from-a-list-of-numbers-those-without-a-counterpart-in-the-id-fiel

반응형