2014-12-20 2 views
1

Пожалуйста, проверьте схему SQL и запрос на SQL FiddleОшибка SQL Query

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

С уважением

Это то, что я получаю:

| MEM_ID |  MEM_EMAIL | GENDER | EDUCATION | PROFESSION | 
|--------|----------------|--------|-----------|-------------| 
|  1 | [email protected] | Male | (null) |  (null) | 
|  1 | [email protected] | (null) | Graduate |  (null) | 
|  1 | [email protected] | (null) | (null) | Engineer | 
|  2 | [email protected] | Female | (null) |  (null) | 
|  2 | [email protected] | (null) | Graduate |  (null) | 
|  2 | [email protected] | (null) | (null) | Not Working | 

, но мне нужно

| MEM_ID |  MEM_EMAIL | GENDER | EDUCATION | PROFESSION | 
|--------|----------------|--------|-----------|-------------| 
|  1 | [email protected] | Male | Graduate | Engineer | 
|  2 | [email protected] | Female | Graduate | Not Working | 

|

+0

скрипку является большим набором вверх, но не могли бы вы описать больше о том, что проблема есть. Каков ваш ожидаемый результат? – Brad

+0

Что ??????????? (извините за все «глупые мини-символы») –

ответ

3

Я думаю, что вы в основном пытаетесь сделать pivot по вашим данным. This is one way для этого.

Результат выглядит следующим образом

EM_ID MEM_EMAIL GENDER EDUCATION PROFESSION 
1 [email protected] Male Graduate Engineer 
2 [email protected] Female Graduate Not Working 
+0

Я собираюсь добавить еще несколько таблиц поиска - **, как вы думаете, следует ли использовать отдельные таблицы поиска или текущую схему? ** –

+0

вы говорите 18 поисковых запросов? Это очень много, и ваш ERD будет выглядеть * messier, но @Dour прав, что SQL, необходимый для каждого запроса, который вы когда-либо пишете на этой таблице, будет очень сложным, если вы будете придерживаться ультра-нормированной схемы. То, что у вас есть, очень нормализовано, но есть баланс, который нужно поразить. – Brad

+0

Это не «очень нормализованный»; он является ненормализованным.Он пытается хранить разные типы данных в одном столбце, что нарушает первую нормальную форму. –

3

Вот что вам нужно ...

SQL Fiddle

SELECT M.mem_Id, 
M.mem_email, 
( SELECT AA.att_value 
    FROM tbl_mem_att_values mv 
    JOIN tbl_attributes AA ON AA.att_id = mv.att_id 
    JOIN tbl_types TG ON TG.type_name = 'Gender' AND TG.type_id = aa.type_id 
    WHERE mv.mem_id = M.mem_Id) AS Gender, 

( SELECT AA.att_value 
    FROM tbl_mem_att_values mv 
    JOIN tbl_attributes AA ON AA.att_id = mv.att_id 
    JOIN tbl_types TG ON TG.type_name = 'Education' AND TG.type_id = aa.type_id 
    WHERE mv.mem_id = M.mem_Id) AS Education, 

( SELECT AA.att_value 
    FROM tbl_mem_att_values mv 
    JOIN tbl_attributes AA ON AA.att_id = mv.att_id 
    JOIN tbl_types TG ON TG.type_name = 'Profession' AND TG.type_id = aa.type_id 
    WHERE mv.mem_id = M.mem_Id) AS Profession 

FROM tbl_members M 

Брэд бить меня на 6 секунд

+0

Большое спасибо –

5

h да, знаменитый Inner-Platform effect, где вы пытаетесь реализовать отношения, создавая таблицы «атрибут-значение» и назначая магические строки для типов и значений данных, затем пытайтесь получить значения с массивными самосоединениями во время выполнения.

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

CREATE TABLE [dbo].Member(
    ID INT PRIMARY KEY, 
    Email Varchar(50) NOT NULL, 
    GenderID INT NOT NULL, 
    EducationID INT, 
    ProfessionID INT 
) 

CREATE TABLE [dbo].Gender(
    GenderID INT PRIMARY KEY, 
    GenderName Varchar(50) NOT NULL 
) 

CREATE TABLE [dbo].Education(
    EducationID INT PRIMARY KEY, 
    EducationName Varchar(50) NOT NULL 
) 

CREATE TABLE [dbo].Profession(
    ProfessionID INT PRIMARY KEY, 
    ProfessionName Varchar(50) NOT NULL 
) 

Назначьте значение магии Gender, Education и Profession строк и назначить их идентификаторы Member. Вы можете выполнять полный поиск простым способом:

SELECT ID, Email, GenderName, EducationName, ProfessionName 
FROM Member m 
    JOIN Gender g ON g.GenderID=m.GenderID 
    LEFT JOIN Education e ON e.EducationID=m.EducationID 
    LEFT JOIN Profession p ON p.ProfessionID=m.ProfessionID 
WHERE ... 

Вы хотите ввести в действие значения? Сделайте столбцы MemberNOT NULL. Хотите разрешить, скажем, только один экземпляр каждой строки Education на члена? Внешние ограничения уже поддерживают это, нет необходимости изобретать свой собственный язык запросов.

+0

_ :) Спасибо. Я пытаюсь использовать только одну таблицу поиска вместо многих, как вы предложили, и будет около 15-18 таблиц поиска (строковые значения), так что ** как вы думаете, я должен быть используя 1 таблицу поиска или много? ** –

+0

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

+0

** нет разных типов данных ** только значения строк –

1

Так же, как альтернатива вы хотите придерживаться стыков:

SELECT  M.mem_Id, 
      M.mem_email, 
      AA.att_value AS Gender, 
      AB.att_value AS Education, 
      AC.att_value AS Profession 
FROM  tbl_members M 

JOIN tbl_mem_att_values mavA ON M.mem_Id = mavA.mem_id 
JOIN tbl_mem_att_values mavB ON M.mem_Id = mavB.mem_id 
JOIN tbl_mem_att_values mavC ON M.mem_Id = mavC.mem_id 

JOIN tbl_types TA ON TA.type_name = 'Gender' 
JOIN tbl_types TB ON TB.type_name = 'Education' 
JOIN tbl_types TC ON TC.type_name = 'Profession' 

LEFT JOIN tbl_attributes AA ON mavA.att_id = AA.att_id AND TA.type_id = AA.type_id 
LEFT JOIN tbl_attributes AB ON mavB.att_id = AB.att_id AND TB.type_id = AB.type_id 
LEFT JOIN tbl_attributes AC ON mavC.att_id = AC.att_id AND TC.type_id = AC.type_id 

WHERE AA.type_id IN (TA.type_id, TB.type_id, TC.type_id) 
AND AB.type_id IN (TA.type_id, TB.type_id, TC.type_id) 
AND AC.type_id IN (TA.type_id, TB.type_id, TC.type_id)