SUM的MAX和在视图中使用TOP

时间:2017-06-11 16:07:36

标签: sql sql-server tsql

我在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表:

'COMMANDLINE'

COMMAND表:

<code>COMMAND</code>

只需要这两个就可以解决问题。我添加了另一个,仅供参考。

示例输出:

老实说,我不确定两个输出是否应该同时“输出”,或者每个输出需要2 VIEWS

OUTPUT

我做了什么:

我查看了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个结果。

2 个答案:

答案 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必须在实际查询中,而不是在视图定义中。