【问题标题】:To select a column from a table using values from another table使用另一个表中的值从一个表中选择一列
【发布时间】:2013-04-18 09:50:00
【问题描述】:

我有如下列的表格:

员工:

Id number(10),  
Name varchar2(10) 

部门:

Id number(10),
Name varchar2(10),
Emp_ids varchar2(10)

表格中的值分别是:

员工:

1,abc,111
2,def,222
3,xyz,333

部门:

111,development,'1,2'
222,testing,'2,3'

我的问题是我需要使用 Department 表中的 emp_ids 列选择员工姓名。

例子:

SELECT names FROM employee 
 WHERE id in (SELECT emp_ids FROM department WHERE name = 'development');

由于emp_ids 是varchar2 数据类型,我无法执行上述命令。

注意:由于我使用 Activerecord Base Connection 从 Ruby 连接我的 Oracle DB,因此我也在标签中包含了 ruby​​。

【问题讨论】:

  • 当你运行代码SELECT names FROM employee WHERE id in (SELECT emp_ids FROM department WHERE name = 'development');时,你得到了什么?
  • 我面临数据类型不匹配错误:ORA-01722: invalid number
  • 那是因为 '1,2' 是一个字符串,不是一个有效的数字。基本上,您有一个 CSV,您需要将其拆分为单独的令牌。有 loads 的示例说明如何在 SO 上执行此操作。查看建议的副本以了解解决方法。
  • 顺便说一句,像这样存储值是一个非常糟糕的主意。甚至比嵌套表列更糟糕。使用关系方法,例如交集表,或使用标准解决方案:DEPT_ID 作为 EMPLOYEE 上的外键。

标签: ruby oracle rubygems oracle10g oracle11g


【解决方案1】:

您的数据模型设计不当。您可以构建一个可行的查询,但它会是:

  1. 比需要的复杂,
  2. 随着数据规模的增长,最终效率会降低,
  3. 容易出现不一致,因为您无法正确定义引用约束,
  4. 肯定是特定于供应商的。

我建议您使用可靠的数据模型。您有 N-N 关系,您需要三个表:

Employee (Id number(10) primary key, Name varchar2(10))
Department (Id number(10) primary key,Name varchar2(10))

Employee_department (
   emp_id number(10) references employee (id),
   dep_id number(10) references department(id),
   constraint pk_emp_dept primary key (emp_id, dep_id)
)

然后您的查询将完美、高效地运行,并且您不会因为数据不一致而彻夜难眠。

SELECT names 
  FROM employee 
 WHERE id in (SELECT ed.emp_id 
                FROM department d
                JOIN employee_department ed ON d.id = ed.dep_id
               WHERE d.name = 'development');

作为数据库开发人员,您的两个主要目标是:

  • 确保数据正确保存到数据库中。没有什么比数据更重要了。如果您不能信任您的数据,那么数据库有什么用?消除不一致是重中之重。
  • 制作一个没有错误的应用程序。如果您的模型合适,您的查询会更简单,您会产生更少的错误,您的应用程序会更快并且通常更可靠。

【讨论】:

  • 是的,文森特你是对的,但我的公司已经设计成这样实施。我们的客户要求提供一个可能有疑问的解决方案
  • @kattashri 有很多方法可以将“csv”类型的值列表转换为视图,例如使用a technique from another SO。但是我必须强调,由于数据模型选择不当,这是一种解决方法。您应该始终努力捍卫最合适的数据模型,因为它会使数据管理更容易,应用程序通常更可靠:)
  • @kattashri 恕我直言,您的公司应该重新考虑其对数据模型的选择。贵公司想要使用 csv 列表而不是标准交集表的原因是什么?
  • 是时候开始寻找有能力的公司为其工作了,如果这就是他们构建系统的方式。这会带来一个痛苦的世界。
  • 请注意,由于这是一个 ruby​​ 和 activerecord 系统,连接表的列通常会将 id 作为主键,将employee_id 和 department_id 作为外键(使用复合它们的唯一键,最好是,而不是空值)
【解决方案2】:

我建议你改变你的表结构。

员工:

   id 
   name
   dept_id

部门:

   id 
   name

【讨论】:

  • 这并不能反映所发布的数据所代表的业务规则
  • declare @ids nvarchar(50) declare @strsql nvarchar(500) select @ids = Emp_IDS from tblDepartment where depName='dev' set @ids='''' + REPLACE(@ids,',',''',''') + '''' set @strsql = 'SELECT name FROM tblemployee WHERE convert(nvarchar,id) in ( ' + @ids + ' )' exec sp_executesql @strsql
猜你喜欢
  • 1970-01-01
  • 2019-03-09
  • 1970-01-01
  • 1970-01-01
  • 2011-03-30
  • 2017-11-13
  • 2012-03-04
  • 2015-07-02
  • 1970-01-01
相关资源
最近更新 更多