如何同时从两个单独的表中检索类似的数据?

时间:2012-04-13 17:51:15

标签: sql-server-2000

免责声明:至少可以说,我的SQL技能是基本的。

假设我在同一个数据库的不同表中有两个相似的数据类型。

第一个表名为精装本,字段如下:

hbID | hbTitle | hbPublisherID | hbPublishDate

第二个表名为平装本,其字段包含类似数据但字段名称不同:

pbID | pbTitle | pbPublisherID | pbPublishDate

我需要检索10本最新的精装书和平装书,其中出版商ID为7。

这是我到目前为止所做的:

SELECT TOP 10
    hbID, hbTitle, hbPublisherID, hbPublishDate AS pDate
    bpID, pbTitle, bpPublisherID, pbPublishDate AS pDate
FROM hardback CROSS JOIN paperback
WHERE (hbPublisherID = 7) OR (pbPublisherID = 7)
ORDER BY pDate DESC

每行返回七列,其中至少有三列可能是或可能不是错误的发布者。可能是四个,取决于pDate的内容,如果其他六个列适用于正确的发布者,这几乎肯定会成为一个问题!

为了发布该软件的早期版本,我运行了两个单独的查询,每个查询获取10条记录,然后按日期对它们进行排序并丢弃后十条,但我只是知道必须有这是一种更优雅的方式!

有什么建议吗?

旁白:当我的Mac突然遇到内核恐慌时,我正在回顾我在这里写的内容。重新启动,重新打开我的标签,我输入的所有内容仍然在这里! Stack Exchange站点非常棒:)

2 个答案:

答案 0 :(得分:2)

最简单的方法可能是UNION

SELECT TOP 10 * FROM
(SELECT hbID, hbTitle, hbPublisherID as PublisherID, hbPublishDate as pDate
 FROM hardback
 UNION 
 SELECT hpID, hpTitle, hpPublisher, hpPublishDate
 FROM paperback
) books
WHERE PublisherID = 7

如果您可以拥有相同标题的两个副本(1本平装书,1本精装本),请将UNION更改为UNION ALL;仅UNION就会丢弃重复项。您还可以通过向每个选择添加伪列(例如,在发布日期之后)添加指示其类型的列的列:

hbPublishDate as pDate, 'H' as Covertype

您必须使用“P”将相同的新列添加到查询的平装书的一半。请注意,在第二个查询中,您不必指定列名称;结果集采用第一个名称。两个查询中的所有列数据类型都匹配,也是 - 您不能UNION第一个中的日期列,而第二个中的数字列不会将两列转换为查询中的相同数据类型。

这是一个示例脚本,用于创建两个表并执行上面的选择。它在SQL Server Management Studio中工作正常。请记住在完成后删除这两个表(使用DROP Table tablename)。

use tempdb;
create table Paperback (pbID Integer Identity, 
    pbTitle nvarchar(30), pbPublisherID Integer, pbPubDate Date);
create table Hardback (hbID Integer Identity, 
    hbTitle nvarchar(30), hbPublisherID Integer, hbPubDate Date);

insert into Paperback (pbTitle, pbPublisherID, pbPubDate)
  values ('Test title 1', 1, GETDATE());
insert into Hardback (hbTitle, hbPublisherID, hbPubDate)
  values ('Test title 1', 1, GETDATE());

select * from (
  select pbID, pbTitle, pbPublisherID, pbPubDate, 'P' as Covertype
  from Paperback
  union all
  select hbID, hbTitle, hbPublisherID, hbPubDate,'H' 
  from Hardback) books
order by CoverType;

/* You'd drop the two tables here with
DROP table Paperback;
DROP table HardBack;
*/

答案 1 :(得分:0)

我认为这显然更好,如果您只创建一个表格,并引用另一个表格,其中包含有关条目类别的信息,例如hardbackpaperback。这是我的第一个建议。

顺便问一下,你的编程语言是什么?