Select-sql周周谈-第一周

前言

本文将以若干实例讨论 SELECT-SQL 在Visual FoxPro 与SQL Server 中的应用。我们将采用SQL Server 2000 英语版的示例数据库 Northwind 作为蓝本,笔者已经将此数据库转换为Visual FoxPro的数据,您可以下载使用。笔者的采用的实验环境是:SQL Server 2000(E)、Visual FoxPro 7.0(E)。当然你使用SQL Server 7以及Visual FoxPro 6也同样可以得到效果,毕竟SELECT-SQL是最基本的数据库语句之一……

2001年7月28日 第一周

怎样实验

在Visual FoxPro 中我们直接在命令窗口中输入SQL语句,在SQL Server中我们使用 SQL Query Analyzer。SQL Query Analyzer的启动方法是:开始-》程序-》Microsoft SQL Server-》Query Analyzer 。如下图:

开启程序后如下:

注意:在DataBase栏目中选择NorthWind数据库。

现在就让我们正式开始!

A.在销产品

数据库中有一个产品表-Products,存储着企业历史上所有的销售过的产品,当然包括现在可供销售的产品。之所以不将那些曾经经销过的但现在不销售的产品从数据表中删除,是因为这些数据仍然被其他数据关联着,比如历史的销售记录统计时就要用到它们。Products 表使用DISCONTINUED字段表示某产品经销状况,0-在销、1-不销。所以对于SQL Server来说这句SELECT应该这样写:

SELECT PRODUCTS.PRODUCTID,PRODUCTS.PRODUCTNAME FROM PRODUCTS WHERE PRODUCTS.DISCONTINUED=0

在Visual FoxPro 中这句语句基本与SQL Server一致,只是DISCONTINUED字段在SQL Server是bit型的,也就是Visual FoxPro中的逻辑型。由于笔者使用SQL Server的DST转换NorthWind数据到Visual FoxPro数据的,它自动把bit型转换为逻辑型,所以这句SELECT在Visual FoxPro中应这样写:

SELECT PRODUCTS.PRODUCTID,PRODUCTS.PRODUCTNAME FROM PRODUCTS WHERE PRODUCTS.DISCONTINUED=.F.

B.在销产品并显示它的类别名称

这个问题延续了上一个问题,只是要得到每一种产品类别的名称。Products 表中只有CategoryID字段,CategoryName则在Categories表中。对于这种多表问题,我么们就要连接表了,在SQL Server实现如下:

SELECT PRODUCTS.*,CATEGORIES.CATEGORYNAME FROM PRODUCTS INNER JOIN CATEGORIES ON PRODUCTS.CATEGORYID=CATEGORIES.CATEGORYID
WHERE PRODUCTS.DISCONTINUED=0

PRODUCTS INNER JOIN CATEGORIES ON PRODUCTS.CATEGORYID=CATEGORIES.CATEGORYID的意思是:产生一个集合,条件是两个来源表的CATEGORYID相等。

那么SQL Server怎样产生这个集合呢?

其实计算机做了一件很傻的事情:将第个表的每一行与第二个表的每一行连接,这样就会形成N*M行数据(N表示第一个表的行数,M表示第二个表的行数,就本例而言是77*8)。

例如:第一个表如下:

col_a col_b
1 a
2 b

第二个表如下:

col_c col_d
1 1
2 2
3 1
4 2
5 2

TABLE1 INNER JOIN TABLE2 ON TABLE1.COL_A=TABLE2.COL_D

中间集合如下:(2*5=10)

col_a col_b col_c col_d
1 a 1 1
1 a 2 2
1 a 3 1
1 a 4 2
1 a 5 2
2 b 1 1
2 b 2 2
2 b 3 1
2 b 4 2
2 b 5 2

计算机做的第二件事就是:用连接条件参选结果集的数据。本例中就是ON TABLE1.COL_A=TABLE2.COL_D,在偌大的集合中砍掉连接字段不合要求的记录,下表中没有突出显示的数据就是被砍去的数据。

col_a col_b col_c col_d
1 a 1 1
1 a 2 2
1 a 3 1
1 a 4 2
1 a 5 2
2 b 1 1
2 b 2 2
2 b 3 1
2 b 4 2
2 b 5 2

于是就形成了下面的中间集合:

col_a col_b col_c col_d
1 a 1 1
1 a 3 1
2 b 2 2
2 b 4 2
2 b 5 2

接着这个简单的例子,补完整SQL语句:SELECT TABLE2.COL_C,TABLE1.COL_B FROM TABLE1 INNER JOIN TABLE2 ON TABLE1.COL_A=TABLE2.COL_D WHERE TABLE2.COL_C>3

计算机会根据Where字句的内容在中间集合中过滤去不合条件的数据,这里的结果是:

col_a col_b col_c col_d
1 a 1 1
1 a 3 1
2 b 2 2
2 b 4 2
2 b 5 2

进行到这里,计算机就会选择合适的列将最终结果列示给用户:

col_c col_b
4 b
5 b

对于本例的SQL,SQL Server处理的思路基本与我们这个简单的例子一样,我们就不详细说明了。在Visual FoxPro中的SELECT 的写法是:

SELECT PRODUCTS.*,CATEGORIES.CATEGORYNAME FROM PRODUCTS INNER JOIN ;
CATEGORIES ON PRODUCTS.CATEGORYID=CATEGORIES.CATEGORYID WHERE PRODUCTS.DISCONTINUED=.T.

C.列示供应商与客户

供应商信息来源于Suppliers表,客户信息来源于Customers表,只要将两个表接在一起答案就有了。在SQL Server中可以这样写:

SELECT CITY,COMPANYNAME,CONTACTNAME,'CUSTOMERS' AS RELATIONSHIP FROM CUSTOMERS
UNION ALL
SELECT CITY,COMPANYNAME,CONTACTNAME,'SUPPLIERS' FROM SUPPLIERS

在Visual FoxPro中几乎可以复制这条语句,然而事实上在这里你不能执行它。这是因为:相关字段的长度不一样,即使字段类型一致,即c(40)与c(41)是不可以连接的。在SQL Server中就没有这样苛刻的限制。笔者已经调整了Suppliers表中的相关字段的长度,所以您可以方便的使用以下语句:

SELECT CITY,COMPANYNAME,CONTACTNAME,'CUSTOMERS' AS RELATIONSHIP FROM CUSTOMERS ;
UNION ALL SELECT CITY,COMPANYNAME,CONTACTNAME,'SUPPLIERS' FROM SUPPLIERS

D.为打印详细销售情况做准备

这是一个比较复杂的SELECT语句,但它那度不高,只是参与连接的表多了一些,共有6个。作为一张完整的销售单据必须要有:销售基本情况(Orders)、销售明细(Order Details)、产品情况(Products)、销售人员(Employees)、客户情况(Customers)、运输情况(Shippers)。连接这些表的思路与前面的例子中的想法一致:先连接两个表得到中间结果集,这个数据集再与第三个表连接,得到一个数据集合……如此这样就得到了一个庞大的数据集合,于是根据Select 语句的要求提交若干字段。从中我们可以看到:数据集的拼凑才是最主要的工作、最先做的工作!

在SQL Server中的实现如下,值得注意的是表Order details 在Select 语句中用[]扩起来,以便SQL Server 识别。

SELECT ORDERS.SHIPNAME,ORDERS.SHIPADDRESS,ORDERS.SHIPCITY,ORDERS.SHIPREGION,ORDERS.SHIPPOSTALCODE,
ORDERS.SHIPCOUNTRY,ORDERS.CUSTOMERID,CUSTOMERS.COMPANYNAME AS CUSTOMERNAM,
EMPLOYEES.FIRSTNAME+' '+EMPLOYEES.LASTNAME AS SALESPERSON,
ORDERS.ORDERID,ORDERS.ORDERDATE,ORDERS.REQUIREDDATE,
ORDERS.SHIPPEDDATE,SHIPPERS.COMPANYNAME AS SHIPPERNAME,
[ORDER DETAILS].PRODUCTID,PRODUCTS.PRODUCTNAME,[ORDER DETAILS].UNITPRICE,[ORDER DETAILS].QUANTITY,[ORDER DETAILS].DISCOUNT,
[ORDER DETAILS].UNITPRICE*[ORDER DETAILS].QUANTITY*(1-[ORDER DETAILS].DISCOUNT) AS EXTENDEDPRICE, ORDERS.FREIGHT
FROM ((((EMPLOYEES INNER JOIN ORDERS ON EMPLOYEES.EMPLOYEEID=ORDERS.EMPLOYEEID)
INNER JOIN CUSTOMERS ON ORDERS.CUSTOMERID=CUSTOMERS.CUSTOMERID)
INNER JOIN SHIPPERS ON ORDERS.SHIPVIA=SHIPPERS.SHIPPERID)
INNER JOIN [ORDER DETAILS] ON ORDERS.ORDERID=[ORDER DETAILS].ORDERID)
INNER JOIN PRODUCTS ON [ORDER DETAILS].PRODUCTID=PRODUCTS.PRODUCTID

这条语句在Visual FoxPro中几乎不加修改就可以执行了。要注意的仍然是Order Details的表名问题,为方便起见笔者已经把Order Details该为了Order_details,于是语句如下:

SELECT ORDERS.SHIPNAME,ORDERS.SHIPADDRESS,ORDERS.SHIPCITY,ORDERS.SHIPREGION,ORDERS.SHIPPOSTALCODE,;
ORDERS.SHIPCOUNTRY,ORDERS.CUSTOMERID,CUSTOMERS.COMPANYNAME AS CUSTOMERNAM,;
EMPLOYEES.FIRSTNAME+' '+EMPLOYEES.LASTNAME AS SALESPERSON,;
ORDERS.ORDERID,ORDERS.ORDERDATE,ORDERS.REQUIREDDATE,;
ORDERS.SHIPPEDDATE,SHIPPERS.COMPANYNAME AS SHIPPERNAME,;
ORDER_DETAILS.PRODUCTID,PRODUCTS.PRODUCTNAME,ORDER_DETAILS.UNITPRICE,ORDER_DETAILS.QUANTITY,ORDER_DETAILS.DISCOUNT,;
ORDER_DETAILS.UNITPRICE*ORDER_DETAILS.QUANTITY*(1-ORDER_DETAILS.DISCOUNT) AS EXTENDEDPRICE, ORDERS.FREIGHT;
FROM ((((EMPLOYEES INNER JOIN ORDERS ON EMPLOYEES.EMPLOYEEID=ORDERS.EMPLOYEEID) ;
INNER JOIN CUSTOMERS ON ORDERS.CUSTOMERID=CUSTOMERS.CUSTOMERID);
INNER JOIN SHIPPERS ON ORDERS.SHIPVIA=SHIPPERS.SHIPPERID);
INNER JOIN ORDER_DETAILS ON ORDERS.ORDERID=ORDER_DETAILS.ORDERID);
INNER JOIN PRODUCTS ON ORDER_DETAILS.PRODUCTID=PRODUCTS.PRODUCTID

本周就到这里,总结一下:我们发现Visual FoxPro的SELECT 语句与SQL Server的SELECT语句很是相似,有时可以不做修改就能使用。不过每一种语言都有自己的规范,在比较时要注意各自的特点,把握住各自的特色。

时间: 2025-01-31 13:59:39

Select-sql周周谈-第一周的相关文章

如果这个月的第一周在这个月<=3天那么这第一周要归为上一个月的. 用 oracle sql?

问题描述 如果这个月的第一周在这个月<=3天那么这第一周要归为上一个月的. 用 oracle sql? 同样,如果这个月的最后一周在这个月 <=3 天,那么这个最后一周要归为下个月的. 解决方案 如果这个月的最后一周在这个月 <=3 天,那么这个最后一周要归为下个月的

Oracle Database 10g:最佳新特性(第一周:闪回查询)

oracle 第一周:闪回查询 得到电影而不是图片:闪回版本查询 不需要设置,立即识别对行的所有更改 在 Oracle9i Database 中,我们看到它推出了以闪回查询形式表示的"时间机器".该特性允许 DBA 看到特定时间的列值,只要在还原段中提供该数据块此前镜像的拷贝即可.但是,闪回查询只提供某时刻数据的固定快照,而不是在两个时间点之间被更改数据的运行状态表示.某些应用程序,如涉及到外币管理的应用程序,可能需要了解一段时期内数值数据的变化,而不仅仅是两个时间点的数值.由于闪回版

怎样计算当前日期属于这年的第几周。每周从星期一算起,这一年的第一周是从星期一算起,所以第一周的第一天不一定是1月1号

问题描述 怎样计算当前日期属于这年的第几周.每周从星期一算起,每一年的第一周都是是从星期一算起,所以第一周的第一天不一定是1月1号.一年有52周,例如2011年第一周就是2011-01-03至2011-01-09.2012年第一周就是2012-01-02至2012-01-08.现在我传一个日期计算是这年的哪周,结果应该是1-52之间的数字,请各位大侠帮忙 解决方案 解决方案二: 解决方案三:引用1楼的回复: http://blog.csdn.net/allen3010/article/detai

王利芬“日记”:创业第一周

文|<中国企业家>记者 孙雅男 当王利芬还是央视知名创业选秀节目<赢在中国>总制片人兼主持人的时候,每次在录制现场,看着身边形形色色各怀雄心的创业者,总有那么几分钟,王利芬会不由自主的走神,悄悄想,"如果我是他,那会怎样?" 现在,"如果"成为了现实.这是她创业现实的第一周. 2010年3月17日,农历二月二,龙抬头 高调上线 午夜零点,北京Soho现代城顶层一座上下两层1900平米的办公室,依然灯火通明,一群在这里工作的年轻人正在等待一家新

7月第一周.COM增近8万 色情域名.XXX仅增14个

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 IDC评述网(idcps.com)07月09日报道:据Registrar Stats最新数据显示,截至2013年7月8日,全球.COM域名注册总量达到了109,149,317个,环比上周新增79,833个.而亚洲顶级域名.ASIA则新增3,242个,色情域名.XXX净增14个.下面,IDC评述网与大家一起关注全球十大顶级域名最新动态. (图1

sql-DATE_FORMATE(date,&amp;amp;#39;%X年-第%V周&amp;amp;#39;)AS WEEK显示第一周为52周

问题描述 DATE_FORMATE(date,'%X年-第%V周')AS WEEK显示第一周为52周 date的时间为2014-01-01 2014-03-31 为什么第一周会显示成第52周,怎么改成正常的第一周.希望不改变周日为每个星期的第一天的初衷.

中国五大顶级域名7月第一周新增1.8万 美国痛失7.5万个

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 中国IDC评述网07月16日报道:据WebHosting.info公布的数据显示,截至2012年7月9日,我国域名总量达到了 5,115,288个,位居全球第三位.而作为全球域名市场最大的美国,域名总量达到了79,720,164个,高居榜首.下面,IDC评述网将于大家一 起了解,在中美两大国家中,.COM ..NET..ORG..INFO和.

携号转网第一周办理者逾千 双向转网较活跃

早报记者昨天从接近http://www.aliyun.com/zixun/aggregation/18501.html">消息人士处获悉,从11月22日正式启动的天津.海南两地携号转网,第一周转网用户过千,其中转入联通的用户最多. 天津.海南两地的携号转网实验期为半年,用户办理携号转网也非常方便,只要带着手机卡和身份证就可以办理携号转网,但是从目前第一周运转的情况看,用户活跃度总体不及外界预期. 相比较而言,由于天津实行双向转网,转网用户比较活跃:海南只能是中国移动用户转网中国联通和中国电

5月第一周中国域名增近8.6万居首 香港新增401个

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 IDC评述网05月09日报道:根据域名统计机构WebHosting.info最新数据,截至3721.html">2014年5月5日,我国域名总量已突破800万,达8,037,672个,仅次美国,位居全球第二名.然而在5月第一周域名净增量统计上,中国域名增量在20家上榜国家中最大,新增近8.6万域名.而中国香港,新增401个域名