反向SQL查询

时间:2010-11-14 13:29:05

标签: sql

我有以下表格:

表1 {ArticleNo(int),ArtDescription(string)}

表2 {ArticleNo(int),年(日期)}

Table1.ArticleNo是主键。 Table2.ArticleNo是引用table1.ArticleNo

的外键

很难解释我想要查询的内容,所以这里有一个简短的例子:


表1

(1,Desk)
(2,Chair)
(3,Ruler)

表2

(1,2000)
(1,2000)
(2,2001)

查询应返回:

1 Desk 2001
2 Chair 2000
3 Ruler 2000
3 Ruler 2001

所有年份(表2中的所有年份)未出售(或其他)的所有文章。


我希望你理解我的例子 - 查询似乎非常复杂。这是我解决方案的方法:

SELECT table1.ArticleNo,table1.ArtDescription,table2.Year
FROM table1
JOIN table2
ON table1.ArticleNo=table2.ArticleNo
WHERE NOT table1.ArticleNo IN (SELECT table2.Year FROM table2);

我尝试了很多不同的东西..我希望你能帮助我!

4 个答案:

答案 0 :(得分:2)

SELECT  t1.*, t2.year
FROM    t1
CROSS JOIN
        (
        SELECT  DISTINCT year
        FROM    t2
        ) t2
WHERE   (t1.id, t2.year) NOT IN
        (
        SELECT  t2.id, t2.year
        FROM    t2
        )

t2 (year, id)上创建一个索引(按此顺序),以使查询快速运行。

答案 1 :(得分:1)

您可以使用cross join创建所有项目+年份组合的列表。然后,您可以使用not exists条件过滤没有销售的行:

select  *
from    t1 items1
cross join    
        (
        select  distinct year
        from    t2 sales1
        ) sales2
where   not exists
        (
        select  *
        from    t2 sales3
        where   sales3.ItemId = items1.ItemId
                and sales3.Year = sales2.Year
        )

答案 2 :(得分:0)

有很多方法可以做到这一点。两个例子:

select
  t1.ArtDescription,
  y.Year
from
  Table1 t1
  join (
    select distinct
      t2.Year
    from
      Table2 t2
  ) y on 1=1
where
  not exists (
    select
      1
    from
      Table2 tx2
    where
      tx2.ArticleNo = t1.ArticleNo and tx2.Year = y.Year)

Oracle(SQL Server可以做同样的事情,使用EXCEPT代替MINUS):

select
  t1.ArtDescription,
  y.Year
from
  Table1 t1
  join (
    select distinct
      t2.Year
    from
      Table2 t2
  ) y on 1=1
MINUS
select
  t12.ArtDescription
  t22.Year
from
  Table1 t12
  join Table2 t22 on t12.ArticleNo = t22.ArticleNo

答案 3 :(得分:0)

SELECT DISTINCT table1.ArticleNo,table1.ArtDescription,table2.Year
    FROM table1 CROSS JOIN table2 
    WHERE table1.ArticleNo != table2.ArticleNo order by table1.ArticleNo;