Mam szereg wartości w bazie danych, które muszę pobrać, aby utworzyć wykres liniowy. Ponieważ nie wymagam wysokiej rozdzielczości, chciałbym ponownie próbkować dane, wybierając co piąty wiersz z bazy danych.
79
SELECT *
FROM (
SELECT
@row := @row +1 AS rownum, [column name]
FROM (
SELECT @row :=0) r, [table name]
) ranked
WHERE rownum % [n] = 1
[n]
w zapytaniu na 5, aby uzyskać co piąty wiersz.@row :=0
z@row :=2
= 1
na= 2
Możesz wypróbować mod 5, aby uzyskać wiersze, w których identyfikator jest wielokrotnością 5. (Zakładając, że masz jakąś kolumnę identyfikatora, która jest sekwencyjna).
select * from table where table.id mod 5 = 0;
źródło
Ponieważ powiedziałeś, że używasz MySQL, możesz użyć zmiennych użytkownika, aby utworzyć ciągłą numerację wierszy. Musisz jednak umieścić to w tabeli pochodnej (podzapytaniu).
SET @x := 0; SELECT * FROM (SELECT (@x:=@x+1) AS x, mt.* FROM mytable mt ORDER BY RAND()) t WHERE x MOD 5 = 0;
Dodałem,
ORDER BY RAND()
aby uzyskać próbkowanie pseudolosowe, zamiast pozwalać co piąty wiersz nieuporządkowanej tabeli na próbkę za każdym razem.Anonimowy użytkownik próbował to edytować, aby zmienić
x MOD 5 = 0
nax MOD 5 = 1
. Zmieniłem go z powrotem na mój oryginał.Dla przypomnienia, w tym stanie można użyć dowolnej wartości z zakresu od 0 do 4 i nie ma powodu, aby preferować jedną wartość nad inną.
źródło
SET @a = 0; SELECT * FROM t where (@a := @a + 1) % 2 = 0;
źródło
Szukałem czegoś takiego. Odpowiedź Taylora i Billa skłoniła mnie do udoskonalenia ich pomysłów.
tabela data1 ma pola read_date, wartość, którą chcemy wybrać co 2d rekord z zapytania ograniczoną zakresem read_date nazwa tabeli pochodnej jest dowolna i tutaj nazywa się DT
pytanie:
SET @row := 0; SELECT * FROM ( SELECT @row := @row +1 AS rownum, read_date, value FROM data1 WHERE read_date>= 1279771200 AND read_date <= 1281844740 ) as DT WHERE MOD(rownum,2)=0
źródło
SET @row := 0; SELECT count(distinct Message) FROM ( SELECT @row := @row +1 AS rownum, Message FROM operations.EventLog WHERE LogTime > now() - interval 6 hour and ProcedureName = 'Do_CDR' ) as DT WHERE MOD(rownum,2)=0;
Możesz użyć tego zapytania,
set @n=2; <!-- nth row --> select * from (SELECT t.*, @rowid := @rowid + 1 AS ID FROM TABLE t, (SELECT @rowid := 0) dummy) A where A.ID mod @n = 0;
lub możesz zastąpić n swoją n-tą wartością
źródło
SELECT * FROM ( SELECT @row := @row +1 AS rownum, posts.* FROM ( SELECT @row :=0) r, posts ) ranked WHERE rownum %3 = 1
gdzie posty to mój stół.
źródło
Jeśli używasz MariaDB 10.2, MySQL 8 lub nowszego, możesz to zrobić bardziej wydajnie i myślę jaśniej, używając typowych wyrażeń tabelowych i funkcji okien .
WITH ordering AS ( SELECT ROW_NUMBER() OVER (ORDER BY name) AS n, example.* FROM example ORDER BY name ) SELECT * FROM ordering WHERE MOD(n, 5) = 0;
Koncepcyjnie tworzy to tymczasową tabelę z zawartością
example
tabeli uporządkowaną wedługname
pola, dodaje dodatkowe pole o nazwie,n
która jest numerem wiersza, a następnie pobiera tylko te wiersze o liczbach, które są dokładnie podzielne przez 5, czyli co 5 wiersz. W praktyce silnik bazy danych często jest w stanie lepiej to zoptymalizować. Ale nawet jeśli nie optymalizuje go dalej, myślę, że jest to bardziej przejrzyste niż iteracyjne używanie zmiennych użytkownika, tak jak to miało miejsce we wcześniejszych wersjach MySQL.źródło
Jeśli nie potrzebujesz numeru wiersza w zestawie wyników, możesz uprościć zapytanie.
SELECT [column name] FROM (SELECT @row:=0) temp, [table name] WHERE (@row:=@row + 1) % [n] = 1
Zastąp następujące symbole zastępcze:
[column name]
listą kolumn, które chcesz pobrać.[table name]
nazwą swojego stołu.[n]
liczbą. np. jeśli potrzebujesz co piąty wiersz, zamień go na 5źródło