2016-12-15 3 views
1

Я ищу точно противоположное тому, что искал Джонатан в этом примере:MySQL: выбор строк по два из трех первичных ключей

How to select multiple rows by multi-column primary key in MySQL?

Имея 3 колонки в качестве первичного ключа (третий является дата), я хочу выбрать все из них без последней. И если нет второй записи для комбинации первых двух основных значений, я не хочу ее вообще выбирать. Подумайте об этом как о версии управления версиями. Структура таблицы содержит больше столбцов, чем три, и я хочу выбрать целые строки.

кажется что-то вроде этого:

{ID1 | ID2 | DATE} | more columns ... 

псевдокод:

SELECT * FROM table WHERE (first and second primary value are the same and exist more than once) AND NOT MAX(date) 

: D

Я хочу, чтобы вывести данные всех предыдущих версий строки, не включая самые последние один.

Заранее благодарим за любые предложения!

ответ

1

ломаются задачи на этапы:

Псевдо логика:

  • Получить набор данных с записями, которые мы хотим исключить
  • Теперь исключают, что набор данных из всего множества

Шаг 1: Получить набор данных только для тех записей, у которых максимальные данные для ID1, ID2

SELECT ID1, ID2, Max(date) date 
      FROM Table 
      GROUP BY ID1, ID2 

Шаг 2: Теперь используйте этот набор данных, чтобы идентифицировать/исключить записи, которые вам не нужны .. a не существует, скорее всего, самый быстрый.

Быстрее ...

SELECT A.* 
FROM TABLE A 
WHERE NOT EXISTS 
(SELECT 1 
FROM (SELECT ID1, ID2, Max(date) date 
     FROM Table 
     GROUP BY ID1, ID2) B 
WHERE A.ID1 = B.ID1 
    and A.ID2 = B.ID2 
    and A.Date = B.Date) 

или в качестве самостоятельного внешнего соединения на подмножестве, медленнее, но дает доступ к дополнительной информации на подмножестве, если это необходимо. (не так много использования в этом примере, но может быть полезно в других обстоятельствах)

Левое соединение в наборе данных показывает те, которые соответствуют максимальной дате, поэтому все остальные записи будут нулевыми, это набор данных, re после ...

SELECT A.* 
FROM TABLE A 
LEFT JOIN (SELECT ID1, ID2, Max(date) date 
      FROM Table 
      GROUP BY ID1, ID2) B 
    on A.ID1 = B.ID1 
and A.ID2 = B.ID2 
and A.Date = B.Date 
WHERE B.ID1 is null 
+0

Ничего себе, это было быстро! Хорошо объяснили и работали! :) –

+0

из-за того, что я не могу редактировать свой комментарий, вот еще один: Вау, это было быстро! Хорошо объяснили и работали! :) первый дает мне именно то, что я искал, второй с левым соединением добавляет столбцы с NULL к моему набору данных, что может мешать реальным данным, не так ли? вы пропустили закрытие -> (<- в вашем первом решении в самом конце :) –

+0

Во-вторых, мы могли бы просто использовать A. * вместо * и нулевые столбцы уйти. и я добавил в отсутствующие). Нулевые столбцы не мешали бы, но они всегда были бы нулевыми, основываясь на критериях присоединения и where where. поэтому бессмысленно, поэтому я добавил A. *. Имейте в виду, что у меня нет данных, поэтому у нас нет возможности «проверить», если мы не будем макетировать данные. – xQbert