2009-02-24 42 views
2

比方說,我有兩個現有的表,「狗」和「貓」:SQL SELECT語法的解決方法

 
dog_name | owner 
---------+------ 
Sparky | Bob 
Rover | Bob 
Snoopy | Chuck 
Odie  | Jon 

cat_name | owner 
---------+------ 
Garfield | Jon 
Muffy | Sam 
Stupid | Bob 

我怎樣寫這個輸出查詢?

 
owner | num_dogs | num_cats 
------+----------+--------- 
Bob |  2 | 1 
Chuck |  1 | 0 
Sam |  0 | 1 
Jon |  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(選擇...)」 型的查詢

相反,「from」後面必須有一個表名。

不幸的是,我不能負擔得起臨時表或使用「select into」子句創建的表 。我需要針對 建議的解決方案採取一些解決方法,其中以這種方式形成嵌套的select子句。

您的意見是?

乾杯

+0

這是什麼樣的數據庫引擎? – 2009-02-24 22:29:35

+0

在我看來,你的「狗」和「貓」表正在乞求與列(名稱,所有者,類型)組合成一個「寵物」表。那麼你會選擇所有者,類型,數量(名稱)從寵物組所有者,類型。我認爲。沒有測試查詢。 – rmeador 2009-02-24 23:03:04

回答

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 
+0

對不起。我確信我嘗試過。 它可以在括號後命名。 謝謝。 – 2009-02-24 22:12:30

+0

此查詢不正確。因爲它假定所有者的整個列表都在兩個表中。即使您將其更改爲LEFT OUTER JOIN,您也假定所有者列表完全位於主表中。要獲得準確的列表,您需要使用UNION ALL方法。 – 2009-02-24 22:14:32

+0

你是對的。我複製了他的SQL,並添加了一個別名 – 2009-02-24 22:20:33

1
  1. 我說你需要添加UNION ALL IO只是UNION,使這個查詢工作。
  2. 你需要命名你的內部選擇。

    SELECT * FROM(SELECT * FROM表)MyInnerSelect

更好的解決方案是創建一個表所有者並加入狗&貓表。

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 
1

「但問題是,SQL不支持 」SELECT * FROM(選擇...)「 類型的查詢」

當然可以。你只需要給它一個名字,如「select * from(select ...)a」

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緊隨子查詢。

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 

注意,計數(dog_name)大概應該是計數(dog_id)......多狗可以具有相同名稱,不同的業主(赫克...相同的名稱相同的所有者可能是允許的)。

請注意添加DISTINCT到計數(..)以更正問題。

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) 

只是因爲我不喜歡某種原因工會和子選擇... :)

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) 
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 
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;