2

「犬」と「猫」という 2 つの既存のテーブルがあるとします。

犬の名前 | オーナー
 ------+------
 スパーキー | ボブ
 ローバー | ローバー ボブ
 スヌーピー | チャック
 オーディ | ジョン

 猫の名前 | オーナー
 ------+------
 ガーフィールド | ジョン
 マッフィー | サム
 愚かな | ボブ

この出力を使用してクエリを作成するにはどうすればよいですか?

所有者 | num_dogs | num_cats
 ------+----------+---------
 ボブ | 2 | 1
 チャック | 1 | 0
 サム | 0 | 1
 ジョン | 1 | 1

私が得た答えは次のクエリです

select owner, sum(num_dogs), sum(num_cats) from
  (select owner, 1 as num_dogs, 0 as num_cats from dogs
   union
   select owner, 0 as num_dogs, 1 as num_cats from cats)
group by owner

しかし問題は、SQL が「select * from (select...)」タイプのクエリをサポートしていないことです。

代わりに、"from" の後にテーブル名が必要です。

残念ながら、一時テーブルまたは「select into」句で作成されたテーブルを持つ余裕はありません。ネストされた選択句がこのように形成される提案されたソリューションには、いくつかの回避策が必要です。

あなたの意見は何ですか?

乾杯

4

10 に答える 10

4

私のSQLは、テーブルに名前を付けるだけです...どのデータベースを使用していますか?

 select owner, sum(num_dogs), sum(num_cats) from
  (select owner, 1 as num_dogs, 0 as num_cats from dogs
   union all
   select owner, 0 as num_dogs, 1 as num_cats from cats) as g
 group by owner
于 2009-02-24T22:05:01.243 に答える
3
create table cats (cat_name varchar(8), owner varchar(8))
create table dogs (dog_name varchar(8), owner varchar(8))
create table owners (owner varchar(8))

insert into owners values ('Jon')
insert into owners values ('Bob')
insert into owners values ('Chuck')
insert into owners values ('Sam')

insert into dogs values ('Sparky', 'Bob')
insert into dogs values ('Rover', 'Bob')
insert into dogs values ('Snoopy', 'Chuck')
insert into dogs values ('Odie', 'Jon')

insert into cats values ('Garfield', 'Jon')
insert into cats values ('Muffy', 'Sam')
insert into cats values ('Stupid', 'Bob')

select 
    owners.owner,
    count(distinct dog_name) as num_dogs,
    count(distinct cat_name) as num_cats
from 
    owners
        left outer join dogs on dogs.owner = owners.owner
        left outer join cats on cats.owner = owners.owner
group by owners.owner

count(dog_name) はおそらく count(dog_id) である必要があることに注意してください...複数の犬が同じ名前の異なる所有者を持つことができます(一体...同じ名前の同じ所有者はおそらく許可されています)。

問題を修正するために、count(..) に DISTINCT を追加することに注意してください。

于 2009-02-24T22:16:20.110 に答える
1

「しかし問題は、SQLが「select * from(select ...)」タイプのクエリをサポートしていないことです」

確かにそうです。「select * from (select...)a」のような名前を付けるだけです。

于 2009-02-24T22:08:09.957 に答える
1

サブクエリをエイリアスする必要があります。

select owner, sum(num_dogs), sum(num_cats)
from (
    select owner, 1 as num_dogs, 0 as num_cats from dogs
    union all
    select owner, 0 as num_dogs, 1 as num_cats from cats
) a
group by owner

aサブクエリの直後に注目してください。

于 2009-02-24T22:09:07.223 に答える
1

楽しみのために、別の方法を次に示します。

select o.owner, nd.numdogs, nc.numcats
from owners o
left join (select owner, count(dog_name) as numdogs
           from dogs
           group by owner) nd on nd.owner=o.owner
left join (select owner, count(cat_name) as numcats
           from cats
           group by owner) nc on nc.owner=o.owner
于 2009-02-24T22:47:09.113 に答える
1
  1. このクエリを機能させるには、 UNION ALL io だけ を UNIONに追加する必要があると思います。
  2. 内部選択に名前を付ける必要があります。

    SELECT * FROM (SELECT * FROM テーブル) MyInnerSelect

より良い解決策は、テーブルの所有者を作成し、犬と猫のテーブルに参加することです。

于 2009-02-24T22:03:58.953 に答える
0

サブクエリをエイリアスする必要があります。

select sq.owner, sum(sq.num_dogs), sum(sq.num_cats) from
    (select owner, 1 as num_dogs, 0 as num_cats from dogs
     union
     select owner, 0 as num_dogs, 1 as num_cats from cats
    ) as sq
group by sq.owner
于 2009-02-24T22:07:10.740 に答える
0

すべての所有者名を含む所有者テーブルを作成できますか? もしそうなら、次のクエリはあなたが求めている出力を提供します:

SELECT
     owners.owner,
     count(distinct dog_name),
     count(distinct cat_name)
FROM
     (
     Owners
     LEFT JOIN cats ON
          owners.owner = cats.owner
     )
LEFT JOIN dogs ON
     Owners.owner = dogs.owner
GROUP BY
     Owners.owner;
于 2009-02-24T22:54:16.833 に答える
0

これに対する別の見方は、必ずしもパフォーマンスではなく、さまざまな方法を強調するためのものです。

SQL Server の場合 -

SELECT 
ISNULL(c.owner, d.owner) AS owner, 
COUNT(d.dog_name) num_dogs, 
COUNT(c.cat_name) num_cats
FROM
dogs d
FULL OUTER JOIN 
cats c
ON 
d.owner = c.owner
GROUP BY
c.owner, d.owner
ORDER BY
ISNULL(c.owner, d.owner)
于 2009-02-24T22:25:48.167 に答える
0
select
coalesce (d.owner, c.owner),
count(distinct d.dog_name) as num_dogs,
count(distinct c.cat_name) as num_cats
from dogs d
full join cats c on d.owner = c.owner
group by coalesce (d.owner, c.owner)

なんらかの理由でユニオンとサブセレクトが好きではないという理由だけで... :)

于 2009-02-24T22:25:02.223 に答える