0

免責事項:控えめに言っても、私のSQLスキルは基本的です。

同じデータベースの異なるテーブルに2つの類似したデータ型があるとしましょう。

最初のテーブルはハードカバーと呼ばれ、フィールドは次のとおりです。

hbID | hbTitle | hbPublisherID | hbPublishDate

2番目のテーブルはペーパーバックと呼ばれ、そのフィールドは同様のデータを保持しますが、フィールドの名前は異なります。

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

これにより、行ごとに7つの列が返され、そのうちの少なくとも3つは、間違った発行元のものである場合とそうでない場合があります。の内容にもよりますが、おそらく4つpDateですが、他の6つの列が正しい発行元のものである場合は、ほぼ確実に問題になります。

このソフトウェアの以前のバージョンをリリースするために、それぞれ10レコードをフェッチする2つの個別のクエリを実行し、日付で並べ替えて下位10を破棄しました、もっとエレガントな方法があるはずです。

助言がありますか?

余談ですが、Macで突然カーネルパニックが発生したときに、ここに書いた内容を確認していました。再起動してタブを再度開いても、入力した内容はすべてここにあります。StackExchangeサイトは素晴らしいです:)

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

同じタイトルのコピーを2つ(ペーパーバック1つ、ハードカバー1つ)持つことができる場合は、を;に変更UNIONします。単独で重複を破棄します。各選択に疑似列を追加することで、それがどの本の種類であるかを示す列を追加することもできます(たとえば、発行日の後)。UNION ALLUNION

hbPublishDate as pDate, 'H' as Covertype

代わりに「P」を使用して、クエリのペーパーバックの半分に同じ新しい列を追加する必要があります。2番目のクエリでは、列名を指定する必要がないことに注意してください。結果セットは、最初の名前から名前を取得します。2つのクエリのすべての列データ型が一致UNIONします。また、クエリで2つの列を同じデータ型に変換せずに、最初の日付列と2番目の数値列を一致させることはできません。

2つのテーブルを作成し、上記の選択を行うためのサンプルスクリプトを次に示します。SQL Server Management Studioでは問題なく機能しDROP Table tablenameます。完了したら、(を使用して)2つのテーブルを削除することを忘れないでください。

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

hardbackまたはのようなエントリのカテゴリに関する情報を保持する別のテーブルへの参照を使用して1つのテーブルのみを作成する場合は、明らかに優れていると思いますpaperback。これが私の最初の提案です。

ちなみに、あなたのプログラミング言語は何ですか?

于 2012-04-13T18:01:25.840 に答える