SQL:使来自颜色-table 的颜色可搜索
SQL: Make colors from color-table searchable
我有一个包含不同颜色卡片的数据库。
一张卡片可以是“无色”或一种或多种颜色:
"红色","绿色","白色","蓝色",""黑色"
卡片在卡片table中,id,名字和一些其他卡信息,
并且 colors 在 Color table with name(例如:"Red"),一个颜色 code(例如:"r")和一个颜色 id
并且有 连接 table 与 card_id 和 color_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 视图..)
您将在此处使用条件聚合。例如,对于红色和蓝色,您想在
处找到卡片
- 两种颜色都存在
- 不存在其他颜色
这意味着如果我为一张卡片计算红色和蓝色,我必须得到 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]
我有一个包含不同颜色卡片的数据库。
一张卡片可以是“无色”或一种或多种颜色: "红色","绿色","白色","蓝色",""黑色"
卡片在卡片table中,id,名字和一些其他卡信息,
并且 colors 在 Color table with name(例如:"Red"),一个颜色 code(例如:"r")和一个颜色 id
并且有 连接 table 与 card_id 和 color_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 视图..)
您将在此处使用条件聚合。例如,对于红色和蓝色,您想在
处找到卡片- 两种颜色都存在
- 不存在其他颜色
这意味着如果我为一张卡片计算红色和蓝色,我必须得到 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]