programing

한 열의 최소값이 있고 다른 열의 값이 지정된 경우 레코드를 선택하려면 어떻게 해야 합니까?

sourcejob 2023. 6. 18. 13:06
반응형

한 열의 최소값이 있고 다른 열의 값이 지정된 경우 레코드를 선택하려면 어떻게 해야 합니까?

다음과 같은 열이 있는 식품 품목이 포함된 데이터베이스 "재고"가 있습니다.

색인 | 날짜 | 범주 | 하위 범주 | 코드 | 설명 | 시작 | 끝

여기서 "날짜"는 재고로 수령된 날짜입니다."시작"이 null이고 날짜가 가장 오래된 각 고유 범주 및 하위 범주의 레코드를 선택하려고 합니다.

저의 초기 시도는 다음과 같습니다.

SELECT MIN(date) as date, category, subcategory, description, code, inventory.index
    FROM inventory 
    WHERE start is null
    GROUP BY category, subcategory

그리고 몇 가지 예외를 제외하고는 각각의 고유한 범주와 하위 범주에 대해 원하는 레코드를 반환했습니다.날짜가 더 이른 레코드(따라서 날짜가 더 늦은 레코드보다 인덱스가 더 높음)를 나중에 추가한 경우 쿼리는 이 레코드의 날짜를 올바르게 반환하지만 나머지 열에 대한 다른 레코드의 값을 반환하여 테이블에 존재하지 않는 하이브리드 행을 만듭니다.이는 필요한 경우 "날짜" 값을 지속적으로 확인하고 업데이트하지만 결과에 값이 로드된 후에는 다른 필드가 변경되지 않는 것과 같습니다.저는 누군가가 여기서 무슨 일이 일어나고 있는지 이해하는 데 도움을 줄 수 있기를 바랍니다.

저는 몇 가지 다른 접근법을 시도했습니다.

MySQL에서 필드에 최소값이 있는 데이터를 선택하는 방법은 무엇입니까?

John Woo는 WHERE 절 안에 중첩된 SELECT 절을 사용할 것을 제안했습니다.그래서, 내 것은 다음과 같습니다.

SELECT * 
                    FROM inventory
                    WHERE 
                    ( SELECT MIN(date) FROM inventory )
                    AND
                    start is null
                    GROUP BY category, subcategory

AND 연산자에 문제가 있는 것으로 보이며, 이것은 "시작이 null" 상태만 평가하고, 어떤 순서에 놓았는지에 관계없이 다른 상태는 무시합니다.한 가지 조건을 제거하면 다른 조건이 올바르게 평가됩니다.

최소값이 있는 고유 행을 선택하기 위한 SQL 쿼리

Ken Clark는 INNER JOIN을 사용할 것을 제안했고, 저는 이를 다음과 같이 수정했습니다.

SELECT inv.*
FROM inventory inv
  INNER JOIN
  (
    SELECT MIN(date) AS date, category, subcategory, description, code, inventory.index
    FROM inventory
    WHERE start is null
    GROUP BY category, subcategory
  ) inv2
  ON inv2.index = inv.index
WHERE inv2.date = inv.date

이 접근 방식은 문제가 있는 행이 생략된 것을 제외하고는 제 초기 시도와 동일한 결과를 반환합니다(최종 WHERE 절을 평가할 때 날짜가 다르기 때문인 것 같습니다).

이런 경우에 무슨 일이 일어나고 있는지 어디서 알 수 있는지에 대한 모든 제안에 감사드립니다.감사해요!

SELECT MIN(date) as date, category, subcategory, description, code, inventory.index
FROM inventory 
WHERE start is null
GROUP BY category, subcategory

세 가지 쿼리 중 하나도 사용하지 않습니다(초기 시도 후에 에서 하위 쿼리 사용).WHEREJOIN는 유효한 표준 SQL입니다. 이는 의열입표 SQL의 입니다.GROUP BY그리고.SELECT. 절일치않습다니지하이▁다▁are▁과만 실행할 수 있습니다. MySQL에서는 모드로만 실행할 수 있습니다.ONLY_FULL_GROUP_BY비활성화됨 - 좋은 방법이 아닙니다.

하위 쿼리를 사용하여 이 문제를 해결하면 외부 쿼리와 다음과 같이 연관시킬 수 있습니다.

select * 
from inventory i
where i.index = (
    select i1.index 
    from inventory i1 
    where i1.category = i.category and i1.subcategory = i.subcategory and i1.start is null 
    order by i1.date, i1.index limit 1
)

.category/subcategory외부 쿼리가 해당 행에서 적절하게 필터링할 수 있도록 하는 튜플입니다.

MySQL 8.0(또는 MariaDB > = 10.2)을 실행하고 있다면 대신 창 기능을 권장합니다(쿼리를 단일 테이블 스캔에서 실행할 수 있도록).

select *
from (
    select i.*, 
        row_number() over(partition by category, subcategory order by i.date, i.index) rn
    from inventory i
    where start is null
) t
where rn = 1

을 얻을 수 .index 함수의 집계 의수경우MIN(date)카테고리 및 하위 카테고리별로 그룹화됩니다.일단 이것들을 가지면,index선택한 레코드의 값을 입력하면 전체 행을 얻을 수 있습니다.

  SELECT inv.*
  FROM inventory inv
  INNER JOIN
  (
    SELECT SUBSTRING(MIN(CONCAT(`date`, `index`)), 11) AS "selectedIndex", `category`, `subcategory`
    FROM `inventory`
    WHERE `start` IS NULL
    GROUP BY `category`, `subcategory`
  ) inv2
  ON inv.`index` = inv2.`selectedIndex`

의 (당신의) 으로 가정합니다.date열은 표준 MySQL 날짜입니다.)

언급URL : https://stackoverflow.com/questions/76314315/how-do-i-select-the-record-with-the-minimum-value-for-one-column-and-where-anoth

반응형