0

我有一个餐桌设备,

这是我在桌面设备中全选时的数据。

select * from equipment

在此处输入图像描述

在此表中设备有字段 radio1,radio2,radio3

该值是来自表格收音机的 ID,这里是表格收音机

select * from radio

在此处输入图像描述

问题是如何加入收音机和设备,我需要radio1,radio2,radio3 值是来自 table radio 的协议

所以价值是

radio1     ||     radio2    ||    radio3    ||
UDP        || Serial Number ||              ||
4

3 回答 3

2

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

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;

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

您的表格将如下所示:

EquipmentID  RadioID
-----------  -------
     1         1
     1         2
-- (notice there's no third row, but you could have 3 or even more)

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

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 列。要适应非规范化的设计,要经历很多笨拙的事情。

在 SQL Fiddle 上查看现场演示

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

于 2013-07-25T06:14:09.267 回答
0

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

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
于 2013-07-25T04:26:03.960 回答
0

你的桌子设计很差,你应该规范你的桌子。但如果你需要像你说的那样。以下将是无效的方法,但请检查它是否有效。

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
于 2013-07-25T04:26:14.447 回答