SQL:使来自颜色-table 的颜色可搜索

SQL: Make colors from color-table searchable

我有一个包含不同颜色卡片的数据库。

一张卡片可以是“无色”或一种或多种颜色: "红色","绿色","白色","蓝色",""黑色"

卡片卡片table中,id,名字和一些其他卡信息,

并且 colorsColor table with name(例如:"Red"),一个颜色 code(例如:"r")和一个颜色 id

并且有 连接 tablecard_idcolor_id

所以问题是如何使颜色可搜索

我希望能够找到所有 "only Red",
的卡片 以及所有 "Red or Blue",
以及所有 "Red and Blue" 的卡片(3,4 和 5 色相同!)

共有 30 种不同的颜色组合:

//000001//000010//000011//000100//000101//000110//000111
//001000//001001//001010//001011//001100//001101//001111
//010000//010001//010010//010011//010100//010101//010110
//010111//011000//011001//011010//011011//011100//011101
//011111
//100000 (Colorless)

我发现 UNION 是可行的,但是
必须做出所有 30 种不同的组合,然后将它们全部组合在一起!

SELECT 
c.id
'false' AS Colors,
'true' AS Red, 
'false' AS Blue
'false' AS Green
'false' AS White
'false' AS Black
'false' AS Colorless
FROM cards_data AS c
INNER JOIN con_cards_colors AS ccc_red ON c.id = ccc_red.cards_id
INNER JOIN colors AS co_red ON co_red.id = ccc_red.colors_id
WHERE
    co_red.name = "Red"

Union
(...)

这似乎不是一个好的解决方案!

所以任何想法都会受到赞赏?

(最佳我喜欢某种 SQL 视图..)

您将在此处使用条件聚合。例如,对于红色和蓝色,您想在

处找到卡片
  1. 两种颜色都存在
  2. 不存在其他颜色

这意味着如果我为一张卡片计算红色和蓝色,我必须得到 2。如果我计算所有颜色,我也必须得到 2。(对于一种、三种或更多颜色也是如此。)

所以使用这个查询,只改变提到的颜色和颜色的数量:

select *
from cards_data where id in
(
  select cards_id
  from con_cards_colors
  group by cards_id
  having count(case when colors_id in (select id from colors where name in ('Red','Blue')) then 1 end) = 2 -- i.e. find all
  and count(*) = 2 -- i.e. find only those and no others
);

这里大概是什么不好的解决方法。 :) 将卡片和颜色作为衍生 table 进行透视,以便稍后将其作为 CTE 进行查询。

--CREATING TABLES 

CREATE TABLE [card] (
    cardID int,
    Name varchar(255),
);

CREATE TABLE color (
    colorID int,
    Name varchar(255),
    );

CREATE TABLE colorcard (
colorID int,
cardID int,);

insert into card (cardID,Name)
values 
(1,'CARDa'),
(2,'CARDb'),
(3,'CARDc')



insert into color (colorID,Name)
values 
(1,'Red'),
(2,'Green'),
(3,'White')

insert into colorcard (colorID,cardID)
values 
(1,1),
(2,1),
(3,2),
(3,3),
(1,3)

-- SHOWING TABLES 

select * from card

select * from color

select card.name,color.name,color.colorid 
from card
    join colorcard on card.cardid = colorcard.cardid
    join color on colorcard.colorid = color.colorid;

-------------------------------QUERY

with cte as (
select cardname, 
    coalesce (red/red,0) as red , 
    coalesce (green/green,0) as green, 
    coalesce (white/white,0) as white,
    ':)' AS [Where is set to CardIsOnlyWhite] -- Comment this out 

from 
    (
    select 
        card.name as cardname
        ,color.name as colorname
        ,color.colorid as colorid
    from card
        join colorcard on card.cardid = colorcard.cardid
        join color on colorcard.colorid = color.colorid
    --where color.name = 'red'  
    ) as colorcard
PIVOT  
(  
AVG(colorid)  
FOR colorname IN (red, green, white)  
) AS PivotTable
)
select *
from cte 

--where cte.white   = 1 ,   -- CARDS WITH WHITE, may or may not have other colors.

where                       -- CARDS WITH ONLY WHITE
        cte.white   = 1 
    and cte.red     = 0
    and cte.green   = 0
  



--DELETE EXERCISE 

truncate TABLE colorcard
truncate TABLE color
truncate TABLE [card]

Drop TABLE colorcard
Drop TABLE color
drop TABLE [card]