MySQL - выбор, где все остальные столбцы = 0 - PullRequest
0 голосов
/ 28 декабря 2011

Предположим, у вас есть таблица со многими полями свойств, например:

id
datetime
q
a
c
d
.
.
.
(etc)

, где q, a, c, d и т. Д. Обозначают неопределенное количество целых полей, имена которых генерируются (такжесоздается во время выполнения)

Как выбрать с ограничением, что некоторые конкретные поля являются определенным числом, а все остальные равны 0?

(например) a = 1, c = 5, а все остальные равны 0?


Обновление:

Я думаю, что я спрашиваю, есть ли какая-то "целостная" функция или что-то, куда я могу просто пойти "ГДЕ ВСЕ ДРУГИЕ = 0" (иличто-то вроде этого).

Проблема с нормализацией заключается в том, что даже после объединения мне все равно приходится проверять как конкретные ненулевые значения, так и все ли поля (или нормализованное поле) 0.


Конкретное применение:

таблица химических соединений

id
name
C
Fe
Cl
H
.
.
.
(etc - fields are added when new compound insert contains elements not listed)

пример строки:

name = Hydrochloric acid
C = 0
Fe = 0
Cl = 1
H = 1
.
.
. 
(everything else = 0)

Проблема с простымSELECT * FROM table WHERE H=1 AND Cl = 1 состоит в том, что он также включает в себя другие случаи, такие как C Cl H (который, хотя он имеет C = 1, выбран потому, что Cl и H также равны 1)

Вот почему япытаясь понять, как его выбрать, где все остальные поля равны 0!

Ответы [ 3 ]

1 голос
/ 28 декабря 2011

Вы не можете иметь неограниченное количество столбцов в таблице - вы ограничены определенным количеством.В этом случае вы просто используете:

... where a = 1 and c = 5 and q = 0 and b = 0 and d = 0 and ...

Если вы просто подразумевали, что количество определено, но число столбцов , используемых вашим приложением, может измениться, то запрос должен будетгенерироваться также во время выполнения, используя ту же информацию.Например, если d не использовался во время выполнения, он был бы исключен из запроса.

Но это очень плохо спроектированная таблица, и вам следует подумать о ее нормализации лучше, например, перенести эти атрибуты вотдельную таблицу (по одному атрибуту на строку в этой новой таблице) и связывание их с исходной таблицей с полем id, например:

BaseTable:
    id          integer        primary key
    datetime    timestamp
OtherTable:
    id          integer        references BaseTable(id)
    attribute   char(1)
    text        varchar(50)
    primary key (id,attribute)

Схема такого типа допускает произвольные атрибуты для каждого id.


Исходя из ваших комментариев о том, что вы изменяете таблицу, основываясь на каком-то внешнем факторе, я думаю, это то, что мы в мире DBA назвали бы "интересным" дизайнерским решением: -)

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

Например, MySQL имеет COLUMNS table в схеме INFORMATION_SCHEMA, которую вы можете использовать для перечисления всех столбцов для данной таблицы.Используя это, вы можете динамически построить действительный оператор SQL на основе произвольно сложной таблицы.

Не говоря уже о том, что это хорошая идея, просто это возможно.

1 голос
/ 28 декабря 2011

Это нереальная ситуация.У вас никогда не будет неопределенного числа полей int, потому что вы не можете просто изменить таблицу без оператора ALTER (только во время выполнения).По крайней мере, вы не должны.

0 голосов
/ 28 декабря 2011

Вы строите что-то вроде этого:

WHERE a=1
  AND c=5
  AND d=0
  AND e=0
  ...

или это:

WHERE (a, c, d, e, ...) =
      (1, 5, 0, 0, ...)

Нет ничего похожего на:

WHERE ALL OTHERS = 0

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


Обновление после редактирования ОП

Возможная нормализация для химических соединений - элементы:

Compound
--------
CompoundId   Int          Primary Key
Name         Varchar(250) Unique
...other stuff

Element
-------
ElementCode  Char(2)      Primary Key
Name         Varchar(50)  Unique 

Structure
---------
CompoundId   Int 
ElementCode  Char(2) 
Ratio        Int
Primary Key (CompoundId, ElementCode) 
Foreign Key (CompoundId)
  References Compound(CompoundId)
Foreign Key (ElementCode)
  References Element(ElementCode)

с данными образца:

CompoundId  Name 
------------------------------
 1          Hydrochloric acid
 2          Water
 3          Glucose

ElementCode  Name 
---------------------
 H           Hydrogen
 C           Carbon
 O           Oxygen 
 Cl          Chlorium 

CompoundId  ElementCode  Ratio 
------------------------------
 1           H            1
 1           Cl           1 
 2           H            2
 2           O            1
 3           H            12
 3           C            6
 3           O            6
...