首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >查询以显示外键

查询以显示外键
EN

Stack Overflow用户
提问于 2013-07-25 04:16:46
回答 3查看 104关注 0票数 0

我有桌子设备,

这是一个数据,当我选择所有的表设备。

代码语言:javascript
运行
复制
select * from equipment

本表中设备有现场radio1,radio2,radio3

值是来自表收音机的ID,这是tabel收音机

代码语言:javascript
运行
复制
select * from radio

问题是如何连接无线电和设备,我需要radio1,radio2,radio3 value是来自表无线电的协议。

所以这个值是

代码语言:javascript
运行
复制
radio1     ||     radio2    ||    radio3    ||
UDP        || Serial Number ||              ||
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-07-25 04:26:14

你的桌子设计很差,你应该把你的桌子标准化。但如果你需要的话。下面的方法将是unefficeint方法,但是检查它是否有效。

代码语言:javascript
运行
复制
select (select protocal from radio where id=equipemnt.radio1 ) as radio1,
(select protocal from radio where id=equipemnt.radio2 ) as radio2,
(select protocal from radio where id=equipemnt.radio3 ) as radio3
from equipment
票数 0
EN

Stack Overflow用户

发布于 2013-07-25 06:14:09

您的表违反了数据库规范化的规则。将这些值放入三个单独的列中并不是最好的设计。相反,您应该有一个EquipmentRadio表,其中列EquipmentID, RadioIDEquipment表和Radio表都有外键关系。你可以这样做:

代码语言:javascript
运行
复制
CREATE TABLE dbo.EquipmentRadio (
   EquipmentID int NOT NULL CONSTRAINT FK_EquipmentRadio_EquipmentID
      FOREIGN KEY REFERENCES dbo.Equipment(ID),
   RadioID int NOT NULL CONSTRAINT FK_EquipmentRadio_RadioID
      FOREIGN KEY REFERENCES dbo.Radio(ID),
   CONSTRAINT PK_EquipmentRadio PRIMARY KEY CLUSTERED (EquipmentID, RadioID)
);

INSERT dbo.EquipmentRadio
SELECT
   E.ID
FROM
   dbo.Equipment E
   CROSS APPLY (VALUES
      (E.Radio1),
      (E.Radio2),
      (E.Radio3)
   ) R (RadioID)
WHERE
   R.RadioID IS NOT NULL -- or `> 0` if appropriate
;

ALTER TABLE dbo.EquipmentRadio DROP COLUMN Radio1;
ALTER TABLE dbo.EquipmentRadio DROP COLUMN Radio2;
ALTER TABLE dbo.EquipmentRadio DROP COLUMN Radio3;

当然,不要这样做,特别是删除列部分,除非您确定它都是正确的。要使用此设计,您必须适当地修改前端客户端表单和代码。

你的桌子会是这样的:

代码语言:javascript
运行
复制
EquipmentID  RadioID
-----------  -------
     1         1
     1         2
-- (notice there's no third row, but you could have 3 or even more)

同时,如果您只使用所拥有的三列,则比使用三个单独的子查询更好。

代码语言:javascript
运行
复制
SELECT
   E.ID,
   R.* -- should name the columns explicitly, though
FROM
   dbo.Equipment E
   OUTER APPLY (
      SELECT
         P.*
      FROM
         (
            SELECT U.Radio, R.Protocol
            FROM
               (VALUES
                  ('Radio1', E.Radio1),
                  ('Radio2', E.Radio2),
                  ('Radio3', E.Radio3)
               ) U (Radio, RadioID)
               INNER JOIN dbo.Radio R
                  ON U.RadioID = R.ID
            WHERE
               U.RadioID IS NOT NULL -- or `> 0` if appropriate
         ) X
      PIVOT (Max(X.Protocol) FOR X.Radio IN (Radio1, Radio2, Radio3)) P
   ) R
;

这样做的目的是暂时将3个值撤消到3行(就像规范化的数据库一样),然后在一个连接中将它们连接到Radio,然后再将它们转回3列。为了适应非正规化的设计,这是很多笨重的东西。

查看的Live

注意:在我的演示中,我使用的是NULL而不是0 for Radio3,因为这是与Radio表建立正确的外键关系的唯一方法。但是,“正确”的方法是将无线电列移动到一个新的表中,正如我在上面向您展示的那样。

票数 2
EN

Stack Overflow用户

发布于 2013-07-25 04:26:03

您需要对radio中的每个radio...字段加入一次equipment,使用别名来区分radio表:

代码语言:javascript
运行
复制
SELECT equipment.*, Radio1.protocol, Radio2.protocol, Radio3.protocol 
FROM equipment INNER JOIN radio as Radio1 ON Radio1.id=equipment.radio1 INNER JOIN radio as Radio2 ON Radio2.id=equipment.radio2 INNER JOIN radio as Radio3 ON Radio3.id=equipment.radio3
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17848903

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档