0

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

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

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

hbID | hbTitle | hbPublisherID | hbPublishDate

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

pbID | pbTitle | pbPublisherID | pbPublishDate

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

这是我到目前为止所拥有的:

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 网站很棒 :)

4

2 回答 2

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 个精装本),请将 ; 更改UNIONUNION 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;
*/
于 2012-04-13T18:05:28.540 回答
0

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

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

于 2012-04-13T18:01:25.840 回答