SQLServer Выберите, что объединяет и возвращает результаты, в которых несколько записей объединения соответствуют значениям

Скажем, у меня есть 2 таблицы:

Человек

+-------------+ | Id. Name. | +-------------+ | 1. Hello | | 2. World | +-------------+ 

PersonAttribute

 +------------------------------------------------------+ | Id. PersonId. AttributeName AttributeValue | +------------------------------------------------------+ | 1. 1. Gender M | | 2. 1. WearsGlasses Y | | 3. 1. LikesColorGreen N | | 4. 2. Gender F | | 5. 2. WearsGlasses N | | 6. 2. LikesColorGreen Y | +------------------------------------------------------+ 

Что, если бы я хотел вернуть результаты, где я хотел искать людей, которые соответствовали бы суровому набору атрибутов

Итак, у меня есть 2 вопроса:

как я буду искать людей с таким запросом, как: Пол = F и LikesColorGreen = Y

Что делать, если я хочу, чтобы запрос разрешал произвольный набор атрибутов. Например: таблица запросов задает

QueryAttributeName QueryValue

 +----------------------------------+ | 1. LikesColorGreen N | | 2. WearsGlasses Y | | 3. Gender F | +----------------------------------+ 

Один запрос для «Gender = F и LikesColorGreen = Y»:

 select * from Person p Join PersonAttribute pa on p.id = pa.PersonId and pa.AttributeName = Gender and AttributeValue = F interset select * from Person p Join PersonAttribute pa on p.id = pa.PersonId and pa.AttributeName = LikesColorGreen and AttributeValue = Y 

Есть ли лучший запрос, который получит это?

Как называется такой запрос?

Вы можете попробовать следующее:

  select pid from atts where (aname='Gender' and avalue='M') or (aname='WearsGlasses' and avalue='Y') or (aname='LikesColorGreen' and avalue='Y') group by pid having COUNT(*)=3 

Легко расширить запрос, чтобы проверить дополнительные атрибуты.

Производительность может быть проблемой, но с такой структурой данных вы не можете ожидать слишком многого.

Если у вас есть таблица для соответствия, вы можете попробовать:

 select pid from atts a join att_match m on a.aname=m.aname and a.avalue = m.avalue group by pid having COUNT(*)= (select count(*) from att_match); 

он соответствует всем условиям в таблице «матч-крикет».

То, что вы пытаетесь реализовать, называется моделью атрибута-атрибута (EAV) . Это может дать вам некоторую гибкость в удовлетворении уникальных требований клиента без необходимости изменения кода приложения и структуры базы данных, но также имеет свои недостатки.

Одна вещь, которая повысит вашу производительность, – это создать другую таблицу для атрибутов, чтобы вы использовали [AttributeID] в PersonAttribute вместо текста. Это значительно упростит ваши соединения и уменьшит размер вашей таблицы, который может стать довольно большим, в зависимости от того, сколько добавляемых объектов и атрибутов.

Все атрибуты в ваших примерах – двоичные значения (y / n, m / f … и т. Д.). Если большинство ваших атрибутов являются действительно битовыми флагами, вы можете получить больше знаний о хранении некоторых данных в int, bigint или varbinary fields и иметь таблицу конфигурации, которая распределяет биты для ваших атрибутов. Затем выполните проверку на бит-маске, чтобы узнать, соответствует ли запись вашим параметрам запроса. Вы также можете сделать микс, используя битовые поля и таблицу атрибутов.

В противном случае ваш быстрый запрос, чтобы получить все атрибуты, совпадающие с AND, вероятно, будет вашим стандартным объединением с соответствующими индексами:

 select distinct Person.* from Person join PersonAttribute att1 on Person.PersonID=att1.PersonID and att1.attId = 1 --maps to AGE and att1.AttributeValue BETWEEN 30 AND 40 join PersonAttribute att2 on Person.PersonID=att2.PersonID and att2.attId = 1 --maps to Income and att2.AttributeValue < 200000 join ... etc. 
  • Имея проблемы с возвратом 4 столбцов путем объединения трех таблиц и использования псевдонимов в SQL?
  • SQL: Как показать столбец таблицы как строку?
  • self присоединяется к таблице с данными для условия, поступающим из второй таблицы, и присоединяется к таблице thrid для получения некоторых данных
  • SQL: значение JOIN из таблицы A с таблицей C, если таблица B пуста
  • Соединение замедляет работу sql
  • комбинация запроса количества и столбца
  • SQL Server: объединение в строки через. поле, разделенное запятыми
  • Выберите 3 таблицы с несколькими «on» условиями, влияющими на 9 строк только с одним регистром?
  • Как присоединиться к 3 таблицам в структуре сущностей 6
  • объединение по типу столбца
  • Как добавить строки для каждой даты?
  • Interesting Posts

    Как выбрать булевский столбец на основе другого значения столбца в SQL?

    Как узнать, какое ограничение FOREIGN KEY ссылается на таблицу в SQL Server?

    Как использовать процедуру хранилища для обновления столбца с использованием существующего значения столбца

    SUM – список значений (содержать подзапрос)

    Получение только команды PRINT из процедуры SQL Server в VB.NET

    Создайте функцию со целыми столбцами в качестве входных и выходных данных

    Вставка данных из текстового файла в таблицу SQL Server

    Ошибка при запросе типа nvarchar в webform из SQL Server

    Как подключиться к Microsoft SQL Server 2008 (MSSQL) из Matlab?

    SQL Server не существует или доступ запрещен

    Как выбрать значения нескольких столбцов в отсортированном порядке в mssql?

    Репликация сервера Sql по wan

    Почему ToString () настолько резко ухудшает производительность платформы Entity Framework

    Ошибка проекта данных доступа

    Ошибка SQL Server 2008 Filestream Win32 без сетевого кабеля!

    Давайте будем гением компьютера.