我在SQL Server中有以下表格:
COMMANDLINES
:ID_LINE - ID_COMMAND - ID_ARTICLE - QUANTITY COMMAND
:ID_COMMAND - ID_CLIENT - 价格 - 打印CLIENT
:ID_CLIENT - FULL_NAME - SSN - PH_NUM - MOBILE - USERNAME - PASSWORD ARTICLE
:ID_ARTICLE - DES - NAME - PRICE - TYPE - CURRENT_QTT - MINIMUM_QTT
ID_COMMAND
来自COMMANDLINES
个参考COMMAND.ID_COMMAND
ID_CLIENT
引荐COMMAND
的CLIENT.ID_CLIENT
来自ID_ARTICLE
引荐COMMANDLINES
ARTICLE.ID_ARTICLE
我需要创建一个view
我需要显示拥有最佳客户端的所有COMMANDLINES
(总计PRICE
总数最高的那个)然后我需要订购它们按ID_COMMAND
按降序排列,按ID_LINE
按升序排列。
示例数据:
COMMANDLINE
表:
COMMAND
表:
只需要这两个就可以解决问题。我添加了另一个,仅供参考。
示例输出:
老实说,我不确定两个输出是否应该同时“输出”,或者每个输出需要2 VIEWS
。
我做了什么:
我查看了StackOverflow上关于MAX
的{{1}}的内容,但不幸的是,在这种情况下,它对我没什么帮助。我似乎总是做错了。
我还发现,为了在SUM
中使用ORDER BY
,您需要使用VIEWS
,但我不知道如何正确应用它我需要选择所有TOP
。在我之前的一件事中,我使用了以下COMMANDLINES
:
SELECT TOP
这允许我显示所有create view PRODUCTS_BY_TYPE
as
select top (select count(*) from ARTICLE
where CURRENT_QTT > MINIMUM_QTT)*
from
ARTICLE
order by
TYPE
数据,其中PRODUCT
超过最低排序类型,但我无法弄清楚我的生活,如何将此应用于我目前的情况。
我可以从这样的事情开始:
CURRENT_QTT
但后来我不知道如何应用create view THE_BEST
as
select COMMANDLINE.*
from COMMANDLINE
。
我认为首先,我需要查看最好的客户是谁,TOP
- 查看其ID下的所有SUM
,然后对所有客户端PRICE
进行操作所有客户MAX
。
到目前为止,我能想到的最好的是:
SUM
不幸的是,在create view THE_BEST
as
select top (select count(*)
from (select max(max_price)
from (select sum(PRICE) as max_price
from COMMAND) COMMAND) COMMAND) COMMANDLINE.*
from COMMANDLINE
inner join COMMAND on COMMANDLINE.ID_COMMAND = COMMAND.ID_COMMAND
order by COMMAND.ID_COMMAND desc, COMMANDLINE.ID_LINE asc
select count(*)
下划线为红色(又称第3 COMMAND
字)并且表示“没有为{1的第1列指定列}}”。
编辑:
我想出了一些更接近我想要的东西:
COMMAND
仍然缺少COMMAND
的排序,当输出为2时,我只输出1个结果。
答案 0 :(得分:0)
这里有一些代码,希望能告诉你如何使用top-clause以及另一个approche只显示“top”: - )
/* Creating Tables*/
CREATE TABLE ARTICLE (ID_ARTICLE int,DES varchar(10),NAME varchar(10),PRICE float,TYPE int,CURRENT_QTT int,MINIMUM_QTT int)
CREATE TABLE COMMANDLINES (ID_LINE int,ID_COMMAND int,ID_ARTICLE int,QUANTITY int)
CREATE TABLE COMMAND (ID_COMMAND int, ID_CLIENT varchar(20), PRICE float, PRINTED int)
CREATE TABLE CLIENT (ID_CLIENT varchar(20), FULL_NAME varchar(50), SSN varchar(50), PH_NUM varchar(50), MOBILE varchar(50), USERNAME varchar(50), PASSWORD varchar(50))
INSERT INTO COMMANDLINES VALUES (1,1,10,20),(2,1,12,3),(3,1,2,21),(1,2,30,2),(2,2,21,5),(1,3,32,20),(2,3,21,2)
INSERT INTO COMMAND VALUES (1,'1695152D',1200,0),(2,'1695152D',500,0),(3,'2658492D',200,0)
INSERT INTO ARTICLE VALUES(1, 'A','AA',1300,0,10,5),(2,'B','BB',450,0,10,5),(30,'C','CC',1000,0,5,5),(21,'D','DD',1500,0,5,5),(32,'E','EE',1600,1,4,5),(3,'F','FF',210,2,15,5)
INSERT INTO CLIENT VALUES ('1695152D', 'DoombringerBG', 'A','123','321','asdf','asf'),('2658492D', 'tgr', 'A','123','321','asdf','asf')
GO
/* Your View-Problem*/
CREATE VIEW PRODUCTS_BY_TYPE AS
SELECT TOP 100 PERCENT *
FROM ARTICLE
WHERE CURRENT_QTT > MINIMUM_QTT -- You really don't want >= ??
ORDER BY [Type]
-- why do you need your view with an ordered output? cant your query order the data?
GO
输出:
ID_ARTICLE | DES | NAME | PRICE | TYPE | CURRENT_QTT | MINIMUM_QTT
-------------+-------+-------+-------+------+--------------+-------------
1 | A | AA | 1300 | 0 | 10 | 5
2 | B | BB | 450 | 0 | 10 | 5
3 | F | FF | 210 | 2 | 15 | 5
我希望这就是你要找的东西: - )
-- your top customers
SELECT cli.FULL_NAME, SUM(c.PRICE)
FROM COMMANDLINES as cl
INNER JOIN COMMAND as c
on cl.ID_COMMAND = c.ID_COMMAND
INNER JOIN CLIENT as cli
on cli.ID_CLIENT = c.ID_CLIENT
GROUP BY cli.FULL_NAME
ORDER BY SUM(c.PRICE) DESC -- highest value first
SELECT *
FROM (
-- your top customers with a rank
SELECT cli.FULL_NAME, SUM(c.PRICE) as Price, ROW_NUMBER() OVER (ORDER BY SUM(c.PRICE) DESC) AS RowN
FROM COMMANDLINES as cl
INNER JOIN COMMAND as c
on cl.ID_COMMAND = c.ID_COMMAND
INNER JOIN CLIENT as cli
on cli.ID_CLIENT = c.ID_CLIENT
GROUP BY cli.FULL_NAME
) as a
-- only the best :-)
where RowN = 1
--considerations: what if two customers have the same value?
输出:
FULL_NAME |Price | RowN
----------------+---------+-------
DoombringerBG | 4600 | 1
此致 TGR
===== EDITED =====
你的THE_BEST-View的语法结构:
create view THE_BEST AS
SELECT TOP (
SELECT count(*) as cnt
FROM (
SELECT max(max_price) as max_price
FROM (
SELECT sum(PRICE) AS max_price
FROM COMMAND
) COMMAND
) COMMAND
)
cl.*
FROM COMMANDLINES as cl
INNER JOIN COMMAND as c
ON cl.ID_COMMAND = c.ID_COMMAND
ORDER BY c.ID_COMMAND DESC
,cl.ID_LINE ASC
没有OVER
- 条款:
SELECT TOP 1 *
FROM (
-- your top customers with a rank
SELECT cli.FULL_NAME, SUM(c.PRICE) as Price
FROM COMMANDLINES as cl
INNER JOIN COMMAND as c
on cl.ID_COMMAND = c.ID_COMMAND
INNER JOIN CLIENT as cli
on cli.ID_CLIENT = c.ID_CLIENT
GROUP BY cli.FULL_NAME
) as a
-- only the best :-)
ORDER BY Price DESC
您的PRODUCTS_BY_TYPE没有PERCENT:
CREATE VIEW PRODUCTS_BY_TYPE AS
SELECT TOP (select
SUM(p.rows)
from sys.partitions as p
inner join sys.all_objects as ao
on p.object_id = ao.object_id
where ao.name = 'ARTICLE'
and ao.type = 'U')
*
FROM ARTICLE
WHERE CURRENT_QTT > MINIMUM_QTT -- You really don't want >= ??
ORDER BY [Type]
go
但说实话 - 我永远不会在制作中使用这样的查询...我只发布了这个,因为你需要它用于研究目的......
答案 1 :(得分:0)
你和老师之间很可能存在一些误解。从技术上讲,您可以在视图定义中使用ORDER BY
子句,但它绝不保证查询中使用该视图的行的任何顺序,例如SELECT ... FROM your_view
。在最终ORDER BY
中没有SELECT
,结果集的顺序未定义。服务器返回到客户端的行的顺序仅由查询的最后ORDER BY
确定,而不是由视图定义中的ORDER BY
确定。
在视图定义中使用TOP
的目的是以某种方式限制返回的行数。例如,TOP (1)
。在这种情况下,ORDER BY
指定要返回的行。
在视图中使用TOP 100 PERCENT
不会做任何事情。它不会减少返回的行数,也不能保证返回行的任何特定顺序。
说了这么多,在你的情况下你需要找到一个最好的客户端,所以在子查询中使用TOP (1)
是有意义的。
此查询将返回最佳客户端的ID:
SELECT
TOP (1)
-- WITH TIES
ID_CLIENT
FROM COMMAND
GROUP BY ID_CLIENT
ORDER BY SUM(PRICE) DESC
如果可能有多个客户端具有相同的最高总价,并且您希望返回与所有客户端相关的数据,而不仅仅是一个随机客户端,则使用TOP WITH TIES
。
最后,您需要返回与所选客户端对应的行:
create view THE_BEST
as
SELECT
COMMANDLINE.ID_LINE
,COMMANDLINE.ID_COMMAND
,COMMANDLINE.ID_ARTICLE
,COMMANDLINE.QUANTITY
FROM
COMMANDLINE
INNER JOIN COMMAND ON COMMAND.ID_COMMAND = COMMANDLINE.ID_COMMAND
WHERE
COMMAND.ID_CLIENT IN
(
SELECT
TOP (1)
-- WITH TIES
ID_CLIENT
FROM COMMAND
GROUP BY ID_CLIENT
ORDER BY SUM(PRICE) DESC
)
;
这是视图的使用方式:
SELECT
ID_LINE
,ID_COMMAND
,ID_ARTICLE
,QUANTITY
FROM THE_BEST
ORDER BY ID_COMMAND DESC, ID_LINE ASC;
请注意,ORDER BY ID_COMMAND DESC, ID_LINE ASC
必须在实际查询中,而不是在视图定义中。