问题
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:
Blue apple questions
Small apple questions
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