一些SQL问题

时间:2009-10-29 12:00:38

标签: sql sql-server sql-server-2005

我多年来一直在使用SQL,但主要是在SQL Studio(等)中使用查询设计器来组合我的查询。我最近找到了一些时间来实际“学习”所做的一切,并为自己设定了以下相当简单的任务。在开始之前,我想向SOF社区询问他们对问题的想法,可能的答案以及他们可能提供的任何提示。

问题是;

  1. 查找特定列中具有重复项的所有记录(例如,链接ID在整个表中超过1条记录)
  2. 来自同一查询中的链接表的SUM价格(在select中选择?)
  3. 解释4个连接之间的区别; LEFT,RIGHT,OUTER,INNER
  4. 根据SELECT和WHERE条件将数据从一个表复制到另一个表
  5. 输入欢迎&赞赏。

    克里斯

3 个答案:

答案 0 :(得分:1)

假设您有2个名为的表:

  • [OrderLine],列为[Id,OrderId,ProductId,Qty,Status]
  • [产品],[Id,Name,Price]

1)所有命令的订单行都超过1行(技术上与在OrderId上查找重复项相同:):

select OrderId, count(*) 
from OrderLine
group by OrderId
having count(*) > 1

2)订单1000的所有订单行的总价

select sum(p.Price * ol.Qty) as Price
from OrderLine ol
inner join Product p on ol.ProductId = p.Id
where ol.OrderId = 1000

3)连接之间的区别:

  • 内部联接b =>把所有与b匹配的东西拿走。如果找不到b,将不会返回
  • 左连接b =>拿出所有a,将它们与b匹配,包括a即使找不到b
  • righ join b => b离开加入
  • 外部联接b => (左连接b)联合(右连接b)

4)将订单行复制到历史表:

insert into OrderLinesHistory
(CopiedOn, OrderLineId, OrderId, ProductId, Qty)
select 
  getDate(), Id, OrderId, ProductId, Qty
from 
  OrderLine
where 
  status = 'Closed'

答案 1 :(得分:1)

我建议您首先阅读有关此主题的一些教程。对于在SQL中从初级到中级的人来说,您的问题并不是不常见的问题。 SQLZoo是学习SQL的绝佳资源,请考虑遵循这一点。

回答你的问题:

1)查找特定列中具有重复的所有记录

此处有两个步骤:查找重复记录并选择这些记录。要查找重复记录,您应该按照以下方式执行操作:

select possible_duplicate_field, count(*) 
from   table 
group by possible_duplicate_field 
having count(*) > 1

我们在这里做的是从表中选择所有内容,然后按照我们要检查重复项的字段对其进行分组。计数功能然后给我计算该组中的项目数。 HAVING子句表示我们希望在分组后过滤仅显示具有多个条目的组。

这本身就很好,但它并没有给你带有这些值的实际记录。如果您知道重复值,那么您可以写下:

select * from table where possible_duplicate_field = 'known_duplicate_value'

我们可以在select中使用SELECT来获取匹配列表:

select * 
from table 
where possible_duplicate_field in (
  select possible_duplicate_field 
  from   table 
  group by possible_duplicate_field 
  having count(*) > 1
)

2)来自同一查询中链接表的SUM价格

这是两个表之间的简单连接,其中包含两个SUM:

select sum(tableA.X + tableB.Y) 
from  tableA 
join  tableB on tableA.keyA = tableB.keyB

你在这里做的是将两个表连接在一起,其中这两个表由一个关键字段链接。在这种情况下,这是一个自然的连接,它按照您的预期运行(即从左表中获取右表中具有匹配记录的所有内容)。

3)解释4个连接之间的区别; LEFT,RIGHT,OUTER,INNER

考虑两个表A和B.如果从左到右阅读SQL,则“LEFT”和“RIGHT”的概念在这种情况下会更加清晰。所以,当我说:

select x from A join B ...

左表是“A”,右表是“B”。现在,当您明确地说“LEFT”SQL语句时,您声明要加入的两个表中的哪一个是主表。我的意思是:我先扫描​​哪一张桌子?顺便提一下,如果省略LEFT或RIGHT,则SQL隐式使用LEFT。

对于INNER和OUTER,您声明在其中一个表中不存在匹配项时要执行的操作。 INNER声明您希望主表中的所有内容(使用LEFT或RIGHT声明),其中辅助表中存在匹配的记录。因此,如果主表包含键“X”,“Y”和“Z”,并且辅助表包含键“X”和“Z”,则INNER将仅返回“X”和“Z”记录。两张桌子。

当使用OUTER时,我们会说:从主表和从辅助表匹配的任何内容中提供所有内容。因此,在前面的例子中,我们在输出记录集中得到“X”,“Y”和“Z”记录。但是,字段中的NULL应该来自辅助表中的键值“Y”,因为它不存在于辅助表中。

4)根据SELECT和WHERE标准将数据从一个表复制到另一个表

这是非常微不足道的,我很惊讶你从来没有遇到过它。它是INSERT语句中的一个简单嵌套SELECT(数据库可能不支持 - 如果没有,请尝试下一个选项):

insert into new_table select * from old_table where x = y

这假设表具有相同的结构。如果您有不同的结构,那么您需要指定列:

insert into new_table (list, of, fields) 
    select list, of, fields from old_table where x = y

答案 2 :(得分:-1)

回答#4并且可能至少表现出对SQL的理解以及这不是HW的事实,只是我试图学习最佳实践;

SET NOCOUNT ON;
DECLARE @rc int
if @what = 1
    BEGIN
        select id from color_mapper where product = @productid and color = @colorid;
        select @rc = @@rowcount
        if @rc = 0
        BEGIN
            exec doSavingSPROC @colorid, @productid;
        END
    END
END