如何在PostgreSQL中搜索表中的条目并返回列名或索引

envsm3lx  于 2023-01-12  发布在  PostgreSQL
关注(0)|答案(2)|浏览(346)

我有一个代表一副牌的表,其中有4张牌,每张牌都有一个唯一的ID。现在我想在表中查找特定的牌ID,并找出它是副牌中的哪张牌。
| 卡片1|卡片2|卡片3|卡片4|
| - ------|- ------|- ------|- ------|
| 卡ID 1|卡ID 2|卡ID 3|卡ID 4|
例如,如果我表希望这样,我将执行以下操作:SELECT列名WHERE卡ID 3 IN(卡1,卡2,卡3,卡4)
寻找答案我找到了这个:SQL Server : return column names based on a record's value
但这似乎对PostgreSQL不起作用

mgdq6dx1

mgdq6dx11#

SQL服务器的cross apply是SQL标准的cross join lateral

SELECT Cname
FROM   decks
       CROSS join lateral (VALUES('card1',card1),
                          ('card2',card2),
                          ('card3',card3),
                          ('card4',card4)) ca (cname, data)
WHERE  data = 3

Demonstration.
然而,真正的问题是表的设计,一般来说,如果你有col1,col2,col3 ...你应该使用连接表。

create table cards (
  id serial primary key,
  value text
);

create table decks (
  id serial primary key
);

create table deck_cards (
  deck_id integer not null references decks,
  card_id integer not null references cards,
  position integer not null check(position > 0),

  -- Can't have the same card in a deck twice.
  unique(deck_id, card_id),
  -- Can't have two cards in the same position twice.
  unique(deck_id, position)
);

insert into cards(id, value) values (1, 'KH'), (2, 'AH'), (3, '9H'), (4, 'QH');

insert into decks values (1), (2);

insert into deck_cards(deck_id, card_id, position) values
  (1, 1, 1), (1, 3, 2),
  (2, 1, 1), (2, 4, 2), (2, 2, 3);

我们已经确保一副牌不能有相同的牌,也不能有两张牌在相同的位置。

-- Can't insert the same card.
insert into deck_cards(deck_id, card_id, position) values (1, 1, 3);

-- Can't insert the same position
insert into deck_cards(deck_id, card_id, position) values (2, 3, 3);

可以直接查询卡片的位置。

select deck_id, position from deck_cards where card_id = 3

而且一副牌中的牌数没有任意限制,你可以用触发器来应用一张。
Demonstration.

z31licg0

z31licg02#

这是一个相当糟糕的主意。列名属于数据库结构,而不是数据。因此,您可以选择存储为数据的ID和名称,但您不应该选择列名。实际上,使用您的应用的用户不应该对列名感兴趣;它们可能相当技术性。
更改数据模型并将卡名称与ID沿着存储可能是一个好主意,但我不知道您希望如何处理您的数据。
无论如何,如果您想坚持当前的数据库设计,您仍然可以选择这些名称,方法是将它们包含在查询中:

select
  case when card1 = 123 then 'card1'
       when card2 = 123 then 'card2'
       when card3 = 123 then 'card3'
       when card4 = 123 then 'card4'
  end as card_column
from cardtable
where 123 in (card1, card2, card3, card4);

相关问题