SQL Select语法变通方法

时间:2009-02-24 21:57:05

标签: 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(select ...)” 查询类型

相反,在“from”之后必须有一个表名。

不幸的是,我无法承担临时桌子或桌子的费用 使用“select into”子句创建。我需要一些解决方法 建议的解决方案,其中以这种方式形成嵌套的select子句。

你有什么看法?

干杯

10 个答案:

答案 0 :(得分: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

答案 1 :(得分: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)...多只狗可以拥有相同名称的不同所有者(哎呀......可能允许同名的所有者)。

请注意在计数(..)中添加DISTINCT以纠正问题。

答案 2 :(得分:1)

  1. 我说你需要添加UNION ALL io只是UNION来使这个查询工作。
  2. 您需要为内部选择命名。

    SELECT * FROM(SELECT * FROM Table) MyInnerSelect

  3. 更好的解决方案是创建一个表所有者并加入狗&猫桌。

答案 3 :(得分:1)

“但问题是sql不支持”select * from(select ...)“类型的查询”

确实如此。你只需要给它命名,如“select * from(select ...)a”

答案 4 :(得分: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

答案 5 :(得分: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

答案 6 :(得分: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

答案 7 :(得分: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)

只是因为我不喜欢工会和次级选择......:)

答案 8 :(得分: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)

答案 9 :(得分: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;