SQL Server Architecture

余生长醉 提交于 2019-12-24 09:13:41

问题


This is kind of a tough one to explain. I'm going to try to correlate our issue into a general spec.

I've got a table of questions that needed to be asked based on certain circumstances. For instance, let's say that I have 2 apples. 1 apple is blue and the other apple is red.

Now, I need to be able to assign a question if we have 1 red apple. However, I also need to be able to assign a question for the combination of 1 red apple and 1 blue apple.

What's the best way to architect this? I feel that I've gotten close, but I'm still struggling to complete it.

The FilterGroupID is where they need to be grouped. So, down below, the questionID 3 needs to be queried when we've been given BLUE & SMALL.

SCENARIO I'm given a certain combination of an apple. It's Blue and Small. I need to be able to query these questions that are correlated to this apple. So, I would need ANY question that has a filter type/value that matches. So in this scenario, I would want the following questions:

  1. Blue apple questions

  2. Small apple questions

  3. Blue AND Small apple questions

If you look @ the image below, I've been given an apple that is BLUE & LARGE. The only questions I care (that are stored in the table) about are "Blue apple question". Now, if I was given a blue & small apple, I would care about "blue apple question" AND "blue & small" apple questions. The question "Blue & small apple question" is only shown IF THE APPLE IS BLUE AND SMALL. Meaning, It's not shown if the apple is BLUE AND LARGE.


回答1:


This is a simplified version of the model, with a slightly different terminology so I can understand what I am talking about :-) :

Table: Qualities (Quality)
Records: (Color), (Size).

Table: QualityOptions(ID int, Quality, Option)
Records: (1, Color, Red), (2, Color, Blue), (3, Color, Green), (4, Size, Big),    
          (5, Size, Small)

Table: Questions (Question, QualityOptionID)
Records: (Q1, 1), (Q1, 5), (Q2, 1), (Q3, 4), (Q4, 5), (Q5, 2), (Q5, 4), (Q6, 2)

To improve readability of the example I rewrite the last table and its records as:

Table: Questions (Question, QualityOption)
Records: (Q1, Red), (Q1, Small), (Q2, Red), (Q3, Big), (Q4, Small), (Q5, Blue), 
         (Q5, Big), (Q6, Small)

Table: Items (Item)
Records: (a small blue item), (a blue item), (a red item), (a big blue item)

Table: ItemQualities (Item, QualityOption) - again, simplified!
Records: (a small blue item, small), (a small blue item, blue), (a blue item, blue),
         (a red item, red), (a big blue item, big), (a big blue item, blue)

Suppose that Item = "a small blue item". Query ItemQualities relation to get the qualities small and blue. Query the Questions relation to get candidates: (Q1,small), (Q4,small), (Q5,blue), (Q6,small). You are not finished though: query again Questions to see if there are any other records for the candidate questions Q1, Q4, Q5, Q6. For Q1 there is also (Q1,red), meaning that we must discard Q1. For Q5 there is also (Q5, big) -> discard. So we have our result set: {Q4, Q6}.

Suppose now that Item = "a big blue item", so the ItemQualities table returns big and blue. Candidates from Questions are (Q3,big), (Q5,blue), (Q5,big). Query again Questions to get every other record related to the candidates Q3, Q5. There are no other records returned and we can return {Q3, Q5} as the result.

Demo:

create table Items (Item varchar(100))
create table ItemQualities (Item varchar(100), QualityOption varchar(20))
create table Questions (Question varchar(20), QualityOption varchar(20))

insert Items select 'a small blue item' union all select 'a big blue item'
insert ItemQualities select 'a small blue item', 'small' union all select 'a small blue item', 'blue'
union all select 'a big blue item', 'big' union all select 'a big blue item', 'blue'

insert Questions select 'Q1', 'red' union all select 'Q1','small' 
union all select 'Q2', 'red' union all select 'Q3', 'big' union all select 'Q4', 'small'
union all select 'Q5', 'Blue' union all select 'Q5', 'big' union all select 'Q6', 'small'

select * from items
select * from itemqualities
select * from questions

declare @item varchar(100) = 'a small blue item';


; with x as (
select count(*) cnt, q.Question
from ItemQualities iq join Questions q on iq.QualityOption = q.QualityOption
where item = @item
group by q.Question
)
,
y as 
(
select count(*) cnt, x.Question 
    from x
join Questions q on x.Question = q.Question
    group by x.Question
)
select distinct x.Question from x join y on x.Question = y.Question and x.cnt = y.cnt


来源:https://stackoverflow.com/questions/42566126/sql-server-architecture

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!