`
csstome
  • 浏览: 1477707 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

关于SQL组合查询问题的一个思考

 
阅读更多

这是她问我的问题,我当时理解的不对,告诉她怎么做,后来发现其实是不对的。现在就不再说具体当时是如何讨论的,将问题转化为类似的具体的问题。

问题描述:

以NorthWind数据库为例,现在dbo.Products表位主表,我现在要组合条件查询,例如查询出来

dbo.Products.ProductID,dbo.Products.ProductName,dbo.Products.QuantityPerUnit,dbo.Products.UnitPrice,

dbo.Products.UnitsInStock,dbo.Products.UnitsOnOrder,dbo.Products.ReorderLevel,dbo.Products.Discontinued,

dbo.Suppliers.CompanyName,dbo.Suppliers.ContactName,dbo.Suppliers.Country,dbo.Suppliers.Fax,

dbo.Suppliers.HomePage,dbo.Suppliers.Phone,dbo.Suppliers.PostalCode,

dbo.Categories.CategoryName,dbo.Categories.Description

牵扯到dbo.ProductsINNER JOIN dbo.Suppliers INNER JOIN dbo.Categories三张表

按照dbo.Products.ProductName dbo.Suppliers.ContactNamedbo.Categories.CategoryName来查询。如果是一般的查询我想用下面的sql就完成了:

SELECT

dbo.Products.ProductName,dbo.Products.QuantityPerUnit,dbo.Products.UnitPrice,dbo.Products.UnitsInStock,

dbo.Products.UnitsOnOrder,dbo.Products.ReorderLevel,dbo.Products.Discontinued,

dbo.Suppliers.CompanyName,dbo.Suppliers.ContactName,dbo.Suppliers.Country,dbo.Suppliers.Fax,

dbo.Suppliers.HomePage,dbo.Suppliers.Phone,dbo.Suppliers.PostalCode,

dbo.Categories.CategoryName,dbo.Categories.Description

FROM

dbo.Products

INNER JOIN dbo.Suppliers ON dbo.Products.SupplierID = dbo.Suppliers.SupplierID

INNER JOIN dbo.Categories ON dbo.Categories.CategoryID=dbo.Products.CategoryID

WHERE

dbo.Products.ProductName=''

AND dbo.Suppliers.ContactName=''

AND dbo.Categories.CategoryName=''

基本的连表查询就可以了。而且像这样的查询一般会有三个组合框,只需要后台动态组合条件就行了,例如如果只选择了dbo.Products.ProductNamedbo.Suppliers.ContactName那么我们就可以动态组合成:

SELECT

dbo.Products.ProductName,dbo.Products.QuantityPerUnit,dbo.Products.UnitPrice,dbo.Products.UnitsInStock,

dbo.Products.UnitsOnOrder,dbo.Products.ReorderLevel,dbo.Products.Discontinued,

dbo.Suppliers.CompanyName,dbo.Suppliers.ContactName,dbo.Suppliers.Country,dbo.Suppliers.Fax,

dbo.Suppliers.HomePage,dbo.Suppliers.Phone,dbo.Suppliers.PostalCode,

dbo.Categories.CategoryName,dbo.Categories.Description

FROM

dbo.Products

INNER JOIN dbo.Suppliers ON dbo.Products.SupplierID = dbo.Suppliers.SupplierID

INNER JOIN dbo.Categories ON dbo.Categories.CategoryID=dbo.Products.CategoryID

WHERE

dbo.Products.ProductName=''

AND dbo.Suppliers.ContactName=''

但是问题不是这样的,现在商品表是主表,商品名称是必须选择的(开发的时候当然可以默认给一个选择值),而供货商和商品类型是可选可不选的。要求不管怎么查都要有数据都要显示数据,因为商品名称必选,所以如果查询条件没有供货商和商品类型结果只显示和商品相关的信息就可以了,其他的能显示则显示没有就显示为空就可以了。

问题就是这样的,我当时没有理解对,以为是这种情况:例如在商品表中有个供货商id,但是在供货商表中没有找到,那么用inner join连接肯定不显示任何信息,只要用left join以商品表为主表就可以了。当时我将她的问题理解成inner joinleft joinright join的区别了,所有也没有正确的解答。现在想起了这个问题,不妨找出答案。

(在此说明一下:到这里有些朋友会问,做这样的事情没有意义,实际问题中有这样的问题吗。原因是这里用的库有些不太合适,原问题是牵扯到一个人的基本信息表,一个学历表,一个就业履历表等相关人员信息表,这个时候如果只单独看基本还是有意义的)

其实我们可以这样思考:显示结果是从三个表中组合的,其实就是组合列的问题(其实我们经常组合列,inner joinleft joinright join可以起到组合列的作用,而组合行我们经常用union union all),既然如此我们不妨就按照left join思想将这个问题转化为left join的形式,我们将显示结果分为三类分别在三个表中就可以了,当然本来就是从三个表中查询出来的结果,只是三个表没有关联,我们何不先关联成虚表再用left join连接呢?

SELECT

A.ProductName,A.QuantityPerUnit,A.UnitPrice,A.UnitsInStock,

A.UnitsOnOrder,A.ReorderLevel,A.Discontinued ,

B.CompanyName,B.ContactName,B.Country,B.Fax,

B.HomePage,B.Phone,B.PostalCode,

C.CategoryName,C.Description

FROM

(

--商品

SELECT dbo.Products.ProductID,

dbo.Products.ProductName,dbo.Products.QuantityPerUnit,dbo.Products.UnitPrice,dbo.Products.UnitsInStock,

dbo.Products.UnitsOnOrder,dbo.Products.ReorderLevel,dbo.Products.Discontinued

FROM

dbo.Products

WHERE

dbo.Products.ProductName='Chai'

) AS A

LEFT JOIN

(

--供货商

SELECT dbo.Products.ProductID,

dbo.Products.ProductName,dbo.Products.QuantityPerUnit,dbo.Products.UnitPrice,dbo.Products.UnitsInStock,

dbo.Products.UnitsOnOrder,dbo.Products.ReorderLevel,dbo.Products.Discontinued,

dbo.Suppliers.CompanyName,dbo.Suppliers.ContactName,dbo.Suppliers.Country,dbo.Suppliers.Fax,

dbo.Suppliers.HomePage,dbo.Suppliers.Phone,dbo.Suppliers.PostalCode

FROM

dbo.Products

INNER JOIN dbo.Suppliers ON dbo.Products.SupplierID = dbo.Suppliers.SupplierID

WHERE

dbo.Products.ProductName='Chai'

AND dbo.Suppliers.ContactName='Charlotte Cooper'

)AS B

ON A.ProductID=B.ProductID

LEFT JOIN

(

--种类

SELECT dbo.Products.ProductID,

dbo.Products.ProductName,dbo.Products.QuantityPerUnit,dbo.Products.UnitPrice,dbo.Products.UnitsInStock,

dbo.Products.UnitsOnOrder,dbo.Products.ReorderLevel,dbo.Products.Discontinued,

dbo.Categories.CategoryName,dbo.Categories.Description

FROM

dbo.Products

INNER JOIN dbo.Categories ON dbo.Categories.CategoryID=dbo.Products.CategoryID

WHERE

dbo.Products.ProductName='Chai'

AND dbo.Categories.CategoryName='Beverages'

) AS C

ON A.ProductID=C.ProductID

这样,我们商品名称必选,另外两个条件任意组合就可以了。

分享到:
评论

相关推荐

    [SQL思考题二] 组合角色题目

    这是我花了几千元人民币学来的东西,现在和大家分享了!请支持下,给点分数! 先看题目然后做不出来了看答案,这里的每道题目都是非常经典的

    健康档案管理系统.RAR

    (5) 设计一个实用的工资管理程序,模拟会计的活动,实施工资帐目的存储、查询和更改,系统要求有高度的可靠性和安全性,并能按规定的格式打印工资报表。 (6) 设计一个实用的小型商店销售管理系统,其功能包括: ① ...

    asp.net知识库

    .NET关于string转换的一个小Bug Regular Expressions 完整的在.net后台执行javascript脚本集合 ASP.NET 中的正则表达式 常用的匹配正则表达式和实例 经典正则表达式 delegate vs. event 我是谁?[C#] 表达式计算引擎...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    认真听课、多思考问题、多动手操作、有问题一定要问、多参与讨论、多帮组同学 五、 体系结构 oracle的体系很庞大,要学习它,首先要了解oracle的框架。oracle的框架主要由物理结构、逻辑结构、内存分配、后台进程...

    股票买卖最佳时机leetcode-CS50-Finance-stock-portfolio-2020:C$50Finance,一个网络应用程序

    Finance,一个网络应用程序,您可以通过它管理股票投资组合。 该工具允许您检查真实股票、实际价格和投资组合价值,它还可以让您通过查询 IEX 的股票价格来买入(好吧,“买入”)和卖出(好吧,“卖出”)股票。 您...

    Prisma:用于 Node.js 和 TypeScript 的下一代 ORM-开源

    Prisma Client 是一个查询构建器,它组合了您的思考方式,并从 Prisma 模式中自动生成了为您的应用量身定制的类型。 我们设计的 API 对 SQL 老手和数据库新手来说都是直观的。 VSCode 中的自动完成、linting、格式...

    ASP.NET.4揭秘

    18.1.4 绑定到linq to sql查询597 18.1.5 绑定到web服务598 18.2 使用objectdatasource控件与参数601 18.2.1 使用不同的参数类型604 18.2.2 作为参数传递对象607 18.3 使用objectdatasource控件分页、排序和过滤数据...

    测试培训教材

    一个好的测试管理工具应该能把以上几个阶段都管理起来。 测试人员每时每刻都在度量别人的工作成果,而测试人员的工作成果又由谁来度量呢?度量的标准和依据是什么呢?软件测试的度量是测试管理必须仔细思考的问题。...

    ASP.NET 控件的使用

    16.1.4 绑定到LINQ to SQL查询 502 16.1.5 绑定到Web服务 503 16.2 使用ObjectDataSource控件与参数 506 16.2.1 使用不同的参数类型 509 16.2.2 作为参数传递对象 511 16.3 使用ObjectDataSource控件分页、排序和...

    代码生成器Mgicode生成器JAVA代码生成器

    此时,我们可以站在一个更高的层面去思考开发,开发不仅仅是代码,开发不仅仅是处理代码之间关系,还需要处理与数据存储的关系,与测试部署关系等。 这些关系我们需不需要去体现出来,肯定需要。我们可以把这些关系...

    亮剑.NET深入体验与实战精要2

    因pdf的容量过大分4个压缩包打包,还有一个源码另外下载。 《.NET深入体验与实战精要》作者身为从事.NET一线开发的资深开发专家,常年耕耘技术博客,惠及无数.NET新知。此次将长期的思考、感悟,多年的系统开发、...

    亮剑.NET深入体验与实战精要3

    因pdf的容量过大分4个压缩包打包,还有一个源码另外下载。 《.NET深入体验与实战精要》作者身为从事.NET一线开发的资深开发专家,常年耕耘技术博客,惠及无数.NET新知。此次将长期的思考、感悟,多年的系统开发、...

    leetcode答案-roadmap-wiki:路线图-wiki

    响应式断点和媒体查询 推荐网站 排版 前缀和自动修复器 游戏 骗子 有用 调色板 动画 动画背景 更多的 引导程序 文件 CSS扩展 脚本 文件 编译器 备忘单 函数式编程 块作用域 箭 对象字面量 休息,传播 模板字符串 ...

    写给大家看的面向对象编程书(第3版).[美]Matt Weisfeld(带详细书签).pdf

    1.6.3 接口/实现范型的一个实际例子 13 1.6.4 接口/实现范型的模型 14 1.7 继承 15 1.7.1 超类和子类 16 1.7.2 抽象 16 1.7.3 is-a关系 17 1.8 多态 18 1.9 组合 20 1.9.1 抽象 21 1.9.2 has-a关系 21 ...

    第24次课-1 Spring与Hibernate的整合

    创建HibernateTemplate后,注入一个SessionFactory的引用,就可以执行相关操作了。 HibernateTemplate提供了3个构造函数 HibernateTemplate(SessionFactory sf) HibernateTemplate(SessionFactory sf, boolean ...

    勤哲excel服务器2010教程

    7.4.6 一个模板上多个数据表的显示 104 7.5 熟练操作我的工作台 105 7.5.1 在我的工作台中查找 105 7.5.2 多选单据、批量操作 107 7.5.3 导出数据 108 7.6 自定义打印 110 7.6.1 设置模板的打印格式 111 7.6.2 填报...

Global site tag (gtag.js) - Google Analytics