2009-07-16 5 views
2
| one | two | 
------------- 
| A | 1 | 
| A | 2 | 
| B | 1 | 
| B | 3 | 
| C | 1 | 
| C | 4 | 

Я хотел бы получить не повторяется в любой колонке в запросе, поэтому стандартный SELECT DISTINCT one,two FROM table; или SELECT * FROM table GROUP BY one,two; не совсем работает, потому что он ищет отличие во всех строках, которые в этот случай вернет все 6 строк.несколько столбцов отличаются в MySQL

В идеале, я ищу:

| one | two | 
------------- 
| A | 1 | 
| B | 3 | 
| C | 4 | 

В PHP (и т.д.), я бы просто сделать это с помощью массива для каждого столбца, и если какой-либо столбец был использован ранее, пропустите эту строку. Однако я не уверен, как реализовать это в MySQL.

SELECT * FROM (SELECT * FROM table GROUP BY one) GROUP BY two - почти работает. но поскольку внешний запрос не видит всех альтернатив, он будет пропускать действительные параметры, т. е. внутренняя будет рушиться до A, B, C, но вполне может выбрать все 1s для столбца два, что означало бы, что вторая GROUP BY будет затем свернуть его до 1 строки!

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

+1

Обоснуйте правила запроса. Если есть 2 строки с одним и тем же полем «один», которое вы хотите иметь на выходе? –

+0

В вашем примере вы выбрали 'A - 1', который является первым совпадением, но в двух других вы выбрали второе совпадение. Можете ли вы закрепить свой выбор тем или иным? –

+0

В дополнение к вопросу Клемента - что произойдет, если «C» в столбце один встречается только со значениями в столбце два, которые уже произошли с «A» и «B»? – quosoo

ответ

0

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

Причина, по которой у вас возникло такое трудное время, объясняя, что вы хотите, так это то, что оно основано на человеческом суждении. Вы не сможете сделать это в SQL, пока не сможете качественно описать его на английском языке, и то, что вы хотите, не является качественным, оно процедурное.

Существует несколько способов его приближения, например группировка меньшим столбцом, а затем сортировка по совпадению совпадений, но все они пригодны для использования.

Пока вы не можете дать однозначный, логический критерий выбора, это не будет выполнено. Высказывание «минимальное» не учитывается до тех пор, пока вы не определите минимальное значение, и минимальное значение, которое вам требуется, требует процедурного агрегата behvaior, который вы не можете получить в MySQL.

+0

Вероятно, ближайший вы получите, который не ошибочно исключает строки: выберите отличный * from (выберите * из группы foo по одному) как l union all (выберите * из группы foo на два) в качестве r; – 2009-07-23 22:32:40

+0

Спасибо за ответ, признайтесь, не понимаете разницу между качественным и процедурным - попытайтесь прочитать на этих условиях ... – barryhunter

1

Ну, как выясняется, я нашел ответ;)

CREATE TEMPORARY TABLE table2 ENGINE HEAP SELECT * FROM table;

ALTER IGNORE TABLE table2 ADD UNIQUE (one), ADD UNIQUE (two);

SELECT * FROM table2;

Опцию IGNORE в альтер таблице важно, так как он просто отбрасывает все повторяющиеся строки основанный на уникальном индексе s.

(не знаю, почему не подумал об этом раньше - как используется его для хорошего эффекта в решении «заказ перед группой по» запросам типа)

+0

или курс в реальном запросе имеют WHERE и ORDER BY при первоначальном выборе, что делает его полезно. Экспериментируя с другим порядком, RAND() работает хорошо. – barryhunter