2015-03-23 20 views
9

Mam małą tabelę MySQL (MySQL w wersji 5.6.23):MySQL wiersz podzapytanie porównanie problem

+-----------+-----------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+-----------+-----------------+------+-----+---------+----------------+ 
| id  | int(6) unsigned | NO | PRI | NULL | auto_increment | 
| dividends | float(8,6)  | YES |  | NULL |    | 
+-----------+-----------------+------+-----+---------+----------------+ 

My gdzie klauzula następująca składnię row-subqueries.
Jeśli zrobić:

SELECT id, dividends FROM test 
    where (id,dividends) >= (660,0.5); 

lub

SELECT id, dividends FROM test 
    where (id,dividends) >= (660,CAST(0.5 AS DECIMAL(8,6))); 

uzyskać ten wynik:

+-----+-----------+ 
| id | dividends | 
+-----+-----------+ 
| 660 | 0.500000 | 
| 661 | 0.470000 | 
| 662 | 0.470000 | 
| 663 | 0.470000 | 
| 664 | 2.580000 | 
| 665 | 2.581000 | 
... 

Wydaje mi się, że dywidendy> = 0,5 nie jest brana pod uwagę. Czemu?

Odpowiedz

7

Jesteś za pomocą konstruktorów wierszy. MySQL traktuje je dokładnie tak, jak wierszy tabeli. Zatem WHERE (id,dividends) >= (660,0.5) skutecznie działa tak samo jak:

  1. ORDER BY id,dividends;

  2. Znajdź punkt, w którym (660,0.5) będzie siedzieć w tym porządku;

  3. Filtr tylko dla tych rekordów, które są równe lub większe niż ten punkt w zamówieniu.

W związku z tym jest taki sam jak WHERE (id=660 AND dividends>=0.5) OR id>660.

Wygląda na to, że logika, którą naprawdę chcesz wyrazić, to WHERE id>=660 AND dividends>=0.5.

+0

Oznacza to, że moje zapytanie zwróci wszystkie wiersze (bez filtrowania), które są po punkcie znalezionym w 2.? – Bruckwald

+0

@Bruckwald: Tak (w tym sam punkt). – eggyal

+0

Dziwne. Nie tego się spodziewałem po przeczytaniu dokumentacji mysql. Ale wielkie dzięki za wyjaśnienie! – Bruckwald

0

podzielić warunki, gdzie można uzyskać go do pracy

SELECT id, dividends 
FROM test 
WHERE id >= 660 
AND dividends >= 0.5; 

Kiedy multi-colum IN służy, a indeks jest zdefiniowany tylko w pierwszej kolumnie nie jest używany:

Podobny problem został omówiony tu i mogą być stosowane http://www.percona.com/blog/2008/04/04/multi-column-in-clause-unexpected-mysql-issue/

z bug śledzone tutaj http://bugs.mysql.com/bug.php?id=35819

+4

To nie wyjaśnia, dlaczego oryginalne zapytanie kończy się niepowodzeniem. –

+0

Dzięki, ale zastanawiam się, dlaczego powyższy przykład nie działa.Jeśli użyję '=' zamiast '> =', otrzymam poprawny wynik – Bruckwald

+0

Myślę, że OP wie, czy podzielić warunek tam, gdzie klauzula to zadziała, ale pytanie jest czymś innym – jfun

2

Patrząc na miarę CLA najpierw wszystko, co dotyczy identyfikatora, jest prawdziwe, a następnie wszystko inne jest oceniane, ale nie może kolidować z wynikami pierwszego identyfikatora. Możliwe również, że nie masz żadnego identyfikatora większego niż 660, który ma dywidendę większą niż 0,5.

(id,dividends) >= (660,CAST(0.5 AS DECIMAL(8,6))); 

zapytań SQL zawsze rozpocząć ocenę id pierwszy na wszystkich polach> = 660 ... następnie ocenić dywidend ... można spróbować uruchomić poniższe zapytanie i sprawdzić wyniki

where ((id) >= (660)) AND ((dividends) >= (0.5)); 
+0

I uzyskaj poprawne wyniki, jeśli rozwiń klauzulę where: – Bruckwald