2010-06-24 18 views
14

Jak mogę uruchomić kwerendę MySQL, która wybiera wszystko, co nie jest zerowe? To będzie coś w rodzaju:GDZIE wszystko nie jest NULL

Czy po prostu usunę wszystko i ...?

SELECT * FROM schedule WHERE IS NOT NULL 
+2

Byłoby użyteczne, gdyby dodać przykładowe dane i oczekiwany wynik do pytania – Naktibalda

+1

Nie sądzę, że to by miało jakąkolwiek wpływ na odpowiedź. – Sam

+5

Oczywiście, że ... Nie podałeś nam informacji o tym, co nie powinno być puste ... Przykład może nam pokazać, czego oczekujesz! – Fred

Odpowiedz

18

Będziesz musiał wyraźnie określić stan każdej kolumny, np.

SELECT * 
FROM schedule 
WHERE id IS NOT NULL 
    AND foo IS NOT NULL 
    AND bar IS NOT NULL; -- and so on.. 
+0

Więc nie jest możliwe, aby po prostu uzyskać wszystko, gdzie nie jest null ...cholerny. – Sam

+0

Wierzę, że jest sposób, proszę spojrzeć na moją odpowiedź. – Anax

+0

Anax wpadł mi na pomysł, więc poszedłem szukać. Na samym dole dodałem sposób, aby uczynić go tak, abyś miał instrukcję select, dzięki czemu nie musisz przechodzić przez wiele kolumn. Przydatne, jeśli masz tabelę dynamiczną, na której nie możesz zaktualizować swojego oświadczenia select – Sam

5

To zależy od tego, co masz na myśli dokładnie to, by "wszystko, co nie jest pusta":

  • wszystkie kolumny nie muszą być null

    select * from schedule where col1 is not null AND col2 is not null AND ..

  • przynajmniej jedna kolumna powinien być non-null

    select * from schedule where col1 is not null OR col 2 is not null OR ..

Przynajmniej jest to w jaki sposób to zrobić w "ogólnym sql". Nie wiem, czy MySql ma specjalną składnię do tego.

10

można złączyć pola, aby napisać tylko Where-warunek:

SELECT * 
    FROM SCHEDULE 
WHERE ID || FOO || BAR IS NOT NULL; 
+3

To miły skrót, ale należy go poinformować; to niekoniecznie będzie działać we wszystkich bazach danych. Na przykład, późniejsze wersje Postgres zaakceptują to tylko wtedy, gdy pierwsza kolumna jest typu tekstowego; takie jak varchar, char lub text. Mogę sobie również wyobrazić, że niektóre bazy danych wymagają rzutowania dla każdej kolumny, która nie jest tego typu. – pyrocumulus

+3

Jeśli masz długie pola tekstowe, konkatenacja jest kosztowną operacją. Również długość wyniku może być zbyt długa, powodując błąd. – Kobi

+2

Jeśli masz długie pola tekstowe, możesz użyć: WHERE ID || SUBSTR (FOO, 1,1) || SUBSTR (FOO, 1,1) NIE JEST NIŻE; W ten sposób wyodrębnisz tylko pierwszy znak każdego długiego pola tekstowego. – UltraCommit

0

Jeśli używasz innego języka programowania, w połączeniu z SQL, można przyspieszyć ten proces poprzez zapętlenie poprzez listę kolumnie nazwy i za pomocą parametru zrobić jeśli nie zerowy czek zamiast mieć je wszystkie wpisać indywidualnie np

**code SQL** 

Select * 
FROM Schedule 
WHERE @ColumnName IS NOT NULL 

**code c#** 

for(int i =0; i<parameterArray[].length; i++) 
{ 
command.Parameters.Add(new SqlParameter("ColumnName", parameterArray[i])); 
command.Execute(); 
} 

Sugerowałbym wykorzystaniem transakcji, dzięki czemu można zrobić wyżej w jednej partii po pętli prowadzi przez .

3

Musisz uzyskać listę kolumn tabeli, patrząc na bazę danych information_schema.

Załóżmy, że twoja baza danych nazywa się mydata, a twoja tabela nazywa się mytable. Można uzyskać listę pustych kolumnach tabeli, wydając następujące oświadczenie:

SELECT `COLUMN_NAME` 
FROM `information_schema`.`COLUMNS` 
WHERE `TABLE_SCHEMA` = 'mydata' 
    AND `TABLE_NAME` = 'mytable' 
    AND `IS_NULLABLE` = 'YES' 

Nasza ostateczna kwerenda będzie wyglądać następująco:

SELECT * FROM `mydata`.`mytable` 
WHERE CONCAT(<list of columns>) IS NOT NULL 

Wszystko, czego brakuje obecnie lista pustych kolumn, oddzielone przecinkami.Mamy zamiar użyć funkcji GROUP_CONCAT do wytworzenia końcowego komunikatu, który wykonujemy tak:

SET @query = CONCAT(
    'SELECT * FROM `mydata`.`mytable` WHERE CONCAT(', 
    (SELECT GROUP_CONCAT(COLUMN_NAME) 
     FROM `information_schema`.`COLUMNS` 
     WHERE `TABLE_SCHEMA` = 'mydata' AND 
     `TABLE_NAME` = 'mytable' 
     AND `IS_NULLABLE` = 'YES'), 
    ') IS NOT NULL'); 

PREPARE stmt_name FROM @query; 

EXECUTE stmt_name; 

Referencje:

http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html

3

Właśnie wyglądał na swoje linked question i zgadzam się z odpowiedzią Guffy, że powinieneś znormalizować bazę danych.

Linked Question Image

Powyższe wygląda bardziej jak arkuszu wtedy coś, co należy w RDBMS.

Aby odpowiedzieć na obawy dotyczące tego, w jaki sposób chcesz, aby był wyświetlany. Można napisać kwerendę przestawną i umieścić ją w widoku, aby naśladować bieżącą strukturę tabeli i użyć jej dla kwerendy wyświetlania.

Pozwoli to uniknąć potrzeby użycia jakiejś przerażającej klauzuli WHERE zawierającej 24 kolumny, jeśli chcesz wyszukać dane lub dowiedzieć się, czy jest NULL jak w tym pytaniu.

-2

bym nie to zrobić, ale to replace someone else's horrible idea., zwłaszcza nie rób tego - to jest to, co zaproponował:

SELECT * 
    FROM SCHEDULE 
WHERE ID || FOO || BAR IS NOT NULL; 

nie rób tego albo, ale przynajmniej nie jest tak bad ...

SELECT * 
    FROM SCHEDULE 
WHERE coalesce(ID, FOO, BAR) IS NOT NULL; 

to przynajmniej działa na innych wersjach SQL, a niektóre kompilatory rozszerzy ją do szeregu IS NOT NULL.

Just do what the accepted answer says

0

Wykorzystanie XML, dzięki czemu nie trzeba iterację wszystkich kolumnach:

--Your Source Table 
CREATE TABLE [dbo].[schedule](
    [id] [nchar](10) NULL, 
    [col1] [nchar](10) NULL, 
    [col2] [nchar](10) NULL, 
    [col3] [nchar](10) NULL 
) ON [PRIMARY] 

--I know my result should show items NOT NULL, like id:2,col1,val:'a' 
    INSERT INTO [schedule](id,col1,col2,col3) 
    values 
    (1,null,null,null), 
    (2,'a',null,null), 
    (3,null,'b',null), 
    (4,null,null,null), 
    (5,null,null,'c') 

--temp placeholder table 
CREATE TABLE #tempsch (id VARCHAR(max) not null, schColumns XML) 

--Load temp table with XML version of your table 
INSERT INTO #tempsch (id, schColumns) 
     SELECT s.id, 
      ( SELECT * 
       FROM [schedule] AS x 
       WHERE x.id = s.id 
       FOR XML PATH('bar'), TYPE, ROOT('foo') 
      ) AS xml_format_string 
     FROM [schedule] AS s 


--This select should return all values Where all is NOT NULL 
SELECT id, 
sd.c.value('local-name(.)', 'VARCHAR(MAX)') AS elementName, 
sd.c.value('.', 'VARCHAR(MAX)') AS elementValue 
FROM #tempsch s 
CROSS APPLY schColumns.nodes('/foo/bar/*') sd(c) 
WHERE 
sd.c.value('local-name(.)', 'VARCHAR(MAX)') <> 'id' 
0

to działa tylko z char i varchar typu. Jeśli masz inne typy danych, generuje błąd.

SELECT * 
    FROM SCHEDULE 
WHERE coa 

lesce(ID, FOO, BAR) IS NOT NULL; 

niezgodne typy danych: Oczekiwane CHAR dostał DATE Uwaga: tutaj FOO jest nieaktualny typu.

Powiązane problemy