2013-03-19 61 views
0

我有一个超类型表,我必须从2个子类型a,b中选择1个子类型表。一个子类型不能与另一个一起去,所以对于我来说,我必须检查一个子类型是否包含父类型标识符。我一直在做实验查询,但无法做到正确。IF ELSE语句加入表sql

这是不知何故,我认为:

SELECT * from supertypetable INNER JOIN 
IF (a.id = given.id) then a ON a.id = supertypetable.id 
ELSE b ON b.id = supertetable.id 

job Table 
________________________________ 
|job_id| blach2x.... 
________________________________ 
| 1 | 
| 2 | 
| 3 | 
________________________________ 

partime Table 
________________________________ 
|job_id| blach2x.... 
________________________________ 
| 2 | 
| 3 | 
________________________________ 

fulltime Table 
________________________________ 
|job_id| blach2x.... 
________________________________ 
| 1 | 
|  | 
________________________________ 

我想参加满足我的给定id

+0

您使用的是什么RDBMS? – 2013-03-19 18:23:03

+0

@KyleHale mysql – KevCal 2013-03-19 18:24:48

+0

表A和表B有相同的结构吗? – 2013-03-19 18:25:37

回答

0

这看起来很像一个多态在铁轨/ ActiveRecord的连接表。在这里实现的方式,'超类型'表有两个字段:subtype_id和subtype_type。 subtype_type表有一个字符串,可以很容易地转换成正确的子类型表的名称; subtype_id具有该表中该行的ID。像这样构建你的表格可能会有所帮助。

接下来你要问的问题是你究竟期待在结果中看到什么?如果你想看到超类型表加上所有的子类型表,你可能需要一次一个地加入它们,然后将它们结合在一起。换句话说,首先加入一个子类型表,然后对下一个子表,如果这不是你想要的,也许你可以进一步澄清你的问题。

+0

雅我知道这个解决方案,但我的同事之前没有实现这一点,他们开始导入数据。现在即时通讯这个问题试图把它关闭... – KevCal 2013-03-19 18:41:30

0

如果a.id不能等于b.id你可以做joing两个表,然后做一个UNION,只有表其中ID匹配将返回结果:

SELECT * from supertypetable 
INNER JOIN 
a ON a.id = supertypetable.id 
UNION 
SELECT * from supertypetable 
INNER JOIN 
b ON b.id = supertypetable.id 

如果a.id能等于b.id,那么这是行不通的。但这是一个想法

编辑每个评论: 这种方法只适用于如果a和b的结构相同。

+0

如果a和b不具有完全相同的结构,这也不会工作。 – 2013-03-19 18:30:28

+0

@凯尔......罗杰。我正在做这个假设。我会在问题中说明。 – MikeTWebb 2013-03-19 18:31:56

+0

我刚刚尝试过这一点,它满足第一个选择时工作,但当第二个满意时,数据放在错误列 – KevCal 2013-03-19 18:45:36

0

所以一个简单的建议可能只是:

SELECT * FROM job 
    left join parttime on parttime.job_id = job.job_id 
    left join fulltime on fulltime.job_id = job.job_id 
where job.job_id = @job_id 

然后让你的应用程序弄清楚这两个连接表没有NULL数据并显示。

如果你不介意不一致的数据集,并且总是希望得到正确的返回集(尽管你仍然需要某种应用逻辑,正如你所说的那样,parttime和fulltime的结构是不同的,所以你将如何在没有某种检查的情况下有条件地显示/利用他们的数据?如果你打算做这种检查,你最好先做一下,找出你给定的job_id是什么子类型,然后只需选择合适的查询即可运行)

对不起!题外话!

存储过程可以为你做这个逻辑(去掉了所有的连接,只是一个例子):

CREATE PROCEDURE getSubTypeDATA (@job_id int) 
BEGIN 

IF (SELECT EXISTS(SELECT 1 FROM parttime WHERE job_id = @job_id)) = 1 
BEGIN 
SELECT * from parttime 
END 
ELSE 
BEGIN 
SELECT * from fulltime 
END 

END 

另外,如果你想有一个一致的数据集(适用于应用程序逻辑),为什么不把全职和兼职之间的共同列成UNION语句,并为他们不共享的列创建硬编码的NULL。例如,如果全职看起来像

雇员,DepartmentID的,工资

和兼职看上去像

雇员,DepartmentID的,HourlyRate

你可以做

SELECT job.*, employeeid, departmentid, salary, null as hourlyrate FROM job inner join fulltime on fulltime.job_id = job.job_id 
where job.job_id = ? 
union 
    SELECT job.*, employeeid, departmentid, null as salary, hourlyrate FROM job inner join parttime on parttime.job_id = job.job_id 
where job.job_id = ? 

如果有一百个不同的列,这可能是笨拙的。此外,如果这并不明显,使用完全不同结构但使用相同外键的子类型是一个非常好的线索,表明您正在打破第三种正常形式。

+0

这看起来很有希望。我试试这个,但我不是专家,但在数据库管理...生病尝试谷歌这.. ..顺便谢谢生病发布我的发现后 – KevCal 2013-03-19 18:55:34