8

使用 asp.net mvc 应用程序和 c#。我们正在开发一个搜索页面。

更新了我的答案。请在下面查看我自己的答案并提出建议

不幸的是,select into 在 sql azure http://blogs.msdn.com/b/sqlazure/archive/2010/05/04/10007212.aspx中不起作用

帮我

我有下表来显示我的项目搜索结果

项目表

  • ITEMID、SHOPID、ITEMNAME、DESCRIPTION、PRICE、CATID

商店表

  • SHOPId,标题,CITYID,活动

城市表

  • CITYID、CITYName、REGIONID、CountryISO

类别表

  • 猫号、猫名

这是我的搜索查询,它给出了给定条件的分页结果

DECLARE @unitItems INT=20
DECLARE @sortOrder INT=0
DECLARE @catId INT
DECLARE @search NVARCHAR (100)=''
DECLARE @REGIONID INT=0
DECLARE @cityId INT=0
DECLARE @maxPrice DECIMAL (10, 2)
DECLARE @page INT
DECLARE @currentDate DATETIME2 (0)
set @unitItems=20
set @catId=0
set @sortOrder=0
set @search=''
set @cityId=1
set @maxPrice=0
set @page=1
set @currentDate='2013-02-24 13:14:58.073'

;WITH itemresult AS (
  SELECT IT.ITEMID, IT.ITEMNAME, IT.DESCRIPTION, IT.PRICE,
  IT.CATID, C.CATNAME AS CATNAME,S.HEADER AS SHOPHEADER,CI.CITYNAME AS CITY, 
  ROW_NUMBER() OVER (ORDER BY IT.SHOWDATE DESC) AS RowNumber
  FROM ITEM AS IT INNER JOIN SHOP AS S ON IT.SHOPId = S.ShopId 
  INNER JOIN CITY AS CI ON CI.CITYID = S.CITYID
  INNER JOIN COUNTRY AS CY ON CI.COUNTRYISO = CY.COUNTRYISO 
  INNER JOIN REGION AS R ON CI.REGIONID = R.REGIONID 
  INNER JOIN CITY AS CI2 ON CI2.CITYID = @cityId 
  INNER JOIN CATEGORY AS C ON IT.CATID = C.CATID    

  WHERE S.ACTIVE = 1   

  GROUP BY IT.ITEMID, IT.ITEMNAME, IT.HEADER, IT.DESCRIPTION, IT.PRICE, 
  IT.CATID, IT.SHOWDATE,S.HEADER,C.CATNAME,CI.CITYNAME) 

  SELECT IT.*, CEILING(CAST(RN AS float) / @unitItems) AS UNITPAGES, RN AS UNITROWS 
  FROM itemresult IT 
  INNER JOIN (SELECT Max(RowNumber) AS RN FROM itemresult) SUBQ ON 1=1 
  WHERE IT.RowNumber BETWEEN (@page - 1) * @unitItems + 1 
  AND @unitItems * @page 

问题:

现在的问题是我们要在 UI 中添加新的更改。搜索 UI 现在将显示如下内容

第一个结果集 --> 假设总共找到 230 条记录

您在 Fiddle 中看到的搜索结果

第二个结果集 --> 来自 230 条记录的不同类别和计数

CatId、CatName、TotalCountInSearch

例如:1 本书 25 和 2 运动 43 和 8 其他 52。显示我可以在 UI 中显示如下

  • 所有类别 (120)
  • 书籍 (25)
  • 运动 (43)
  • 其他 (52)

第三个结果集 --> 不同的城市和 230 条记录中的计数

CityId、CityName、TotalCountInSearch

用于在 UI 下方显示

  • 所有城市(10)
  • 钦奈 (4)
  • 班加罗尔 (3)
  • 其他 (3)

我如何检索这些计数和名称,如所有类别、书籍、所有城市等?欢迎任何帮助或建议

单击并在此处查看 SQL Fiddle

我想根据搜索条件获得这些计数。希望从我的程序中检索这个作为另一个结果集

主要更新:

我在这里上传了所有架构和实际动态查询 https://github.com/Padayappa/SQLProblem/blob/master/PaginationIssue

4

4 回答 4

4

尝试这个。我希望这能满足你的期望

CREATE VIEW vSequence AS
WITH itemresult AS (
  SELECT IT.ITEMID, IT.ITEMNAME, IT.DESCRIPTION, IT.PRICE,
  IT.CATID, C.CATNAME AS CATNAME,S.HEADER AS SHOPHEADER,CI.CITYNAME AS CITY,CI.CITYID,
  ROW_NUMBER() OVER (ORDER BY IT.SHOWDATE DESC) AS RowNumber
  FROM ITEM AS IT INNER JOIN SHOP AS S ON IT.SHOPId = S.ShopId
  INNER JOIN CITY AS CI ON CI.CITYID = S.CITYID
  INNER JOIN COUNTRY AS CY ON CI.COUNTRYISO = CY.COUNTRYISO
  INNER JOIN REGION AS R ON CI.REGIONID = R.REGIONID
  INNER JOIN CITY AS CI2 ON CI2.CITYID = 1
  INNER JOIN CATEGORY AS C ON IT.CATID = C.CATID

  WHERE S.ACTIVE = 1

  GROUP BY IT.ITEMID, IT.ITEMNAME, IT.HEADER, IT.DESCRIPTION, IT.PRICE,
  IT.CATID, IT.SHOWDATE,S.HEADER,C.CATNAME,CI.CITYNAME,CI.CITYID)

SELECT * FROM itemresult IT

GO

  SELECT IT.*, CEILING(CAST(RN AS float) / 20) AS UNITPAGES, RN AS UNITROWS
  FROM vSequence IT
  INNER JOIN (SELECT Max(RowNumber) AS RN FROM vSequence) SUBQ ON 1=1
  WHERE IT.RowNumber BETWEEN (1 - 1) * 20 + 1
  AND 20 * 1
GO
SELECT  IT.CATID,RS.CATNAME , CONVERT(varchar(10), SUM(CASE WHEN IT.CATID = CAT.CATID THEN 1 ELSE 0 END)) AS 'Count'
FROM vSequence RS INNER JOIN ITEM IT ON RS.CATID = IT.CATID
INNER JOIN CATEGORY CAT
ON IT.CATID = CAT.CATID GROUP BY IT.CATID,RS.CATNAME
GO
SELECT  CIT.CITYID,CITYNAME,CONVERT(varchar(10), SUM(CASE WHEN CIT.REGIONID =  REG.REGIONID THEN 1 ELSE 0 END)) AS 'Count'
FROM COUNTRY CON INNER JOIN REGION REG
ON CON.COUNTRYISO = REG.COUNTRYISO
INNER JOIN CITY CIT ON CIT.REGIONID =  REG.REGIONID
INNER JOIN  vSequence RS ON CIT.CITYID=RS.CITYID GROUP BY REG.REGIONID,CITYNAME, CIT.CITYID

SQL Fiddle示例。

于 2013-03-04T13:37:47.600 回答
3

正如我从您的评论中了解到的那样,我认为您需要的是获得3 result sets by executing a single stored procedure. 您还想知道查询是否已优化。

我认为你的vSequence VIEW很好(所以,我没有在这里添加我的答案)。您需要create a stored procedure获得using your view如下三个不同的结果集。我已将您在小提琴中声明的变量列表作为存储过程的参数。我已经在每个变量旁边发表了评论。由于您的过滤要求尚不清楚,因此我将它们保留原样。

CREATE PROCEDURE myStoredProcedure 
   @unitItems INT=20, --number of items per page
   @sortOrder INT=0, --not used
   @catId INT, --not in use 
   @search NVARCHAR (100)='', --not used
   @REGIONID INT=0, -- not used
   @cityId INT=0, -- not used
   @maxPrice DECIMAL (10, 2), -- not used
   @page INT, --page number
   @currentDate DATETIME2 (0) -- not used
AS 
BEGIN

    /*
      Query 1
      Note: I have assumed your @page start at 1 and also changed the where clause 
      to bring correct data based on @page & @unitItems parameters 
    */
    SELECT IT.*, CEILING(CAST(RN AS float) / 20) AS UNITPAGES, RN AS UNITROWS
    FROM vSequence IT INNER JOIN (SELECT Max(RowNumber) AS RN FROM vSequence) SUBQ ON 1=1
    WHERE IT.RowNumber BETWEEN (@unitItems * (@page - 1) + 1) AND @unitItems 

    /* Query 2 */
    SELECT  IT.CATID,RS.CATNAME , CONVERT(varchar(10), 
            SUM(CASE WHEN IT.CATID = CAT.CATID THEN    1 ELSE 0 END)) AS 'Count'
    FROM vSequence RS 
              INNER JOIN ITEM IT ON RS.CATID = IT.CATID 
              INNER JOIN CATEGORY CAT ON IT.CATID = CAT.CATID 
    GROUP BY IT.CATID,RS.CATNAME

    /* Query 3 */
    SELECT  CIT.CITYID,CITYNAME,CONVERT(varchar(10), 
            SUM(CASE WHEN CIT.REGIONID =   REG.REGIONID THEN 1 ELSE 0 END)) AS 'Count'
    FROM COUNTRY CON 
             INNER JOIN REGION REG ON CON.COUNTRYISO = REG.COUNTRYISO
             INNER JOIN CITY CIT ON CIT.REGIONID =  REG.REGIONID
             INNER JOIN  vSequence RS ON CIT.CITYID=RS.CITYID 
    GROUP BY REG.REGIONID,CITYNAME, CIT.CITYID
 END

以下是如何执行存储过程Management Studio(请使用适当的参数值):

DECLARE @unitItems INT = 20, 
        @sortOrder INT = 0, 
        @catId INT = 0,
        @search NVARCHAR (100) = '', 
        @REGIONID INT = 0, 
        @cityId INT = 1,
        @maxPrice DECIMAL (10, 2) = 0,
        @page INT = 1,
        @currentDate DATETIME2 (0) = '2013-02-24 13:14:58.073'

EXEC myStoredProcedure 
       @unitItems,
       @sortOrder,
       @catId,
       @search,
       @REGIONID,
       @cityId,
       @maxPrice,
       @page,
       @currentDate

要在您的代码中执行此存储过程,请C#使用参数化查询,DataAdapter如下所示:

DataSet ds = new DataSet();
using (SqlConnection connection =  new SqlConnection("your-Connection-String-here"))
{

    SqlDataAdapter adapter = new SqlDataAdapter();
    adapter.SelectCommand = new SqlCommand("myStoredProcedure", connection);
    adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
    adapter.SelectCommand.Parameters.AddWithValue("@unitItems",20);
    //add other parameters as above here
    adapter.SelectCommand.Parameters.AddWithValue("@page",1); //correct page number
    adapter.Fill(ds);
}

//Now you can access all query results as 
ds.Tables[0]; //results from query1
ds.Tables[1]; //results from query2
ds.Tables[2]; //results from query3
于 2013-03-04T16:40:10.697 回答
1

最后我创建了下面的 SP 并解决了这个问题。

请让我知道这是正确的方法吗?

我使用了临时表、Grouping SETS、Grouping_ID

您可以在此处查看代码https://github.com/Padayappa/SQLProblem/blob/master/PaginationResolved

 CREATE PROCEDURE [dbo].[Item_SearchItems_New]
 (
   @ShopNr INT
,@unitItems INT = 20
,@sortOrder INT = 0
,@language CHAR(2) = 'EN'
,@catId INT
,@search NVARCHAR(100) = ''
,@countryIso NCHAR(2) = ''
,@regionNr INT = 0
,@cityId INT = 0
,@maxPrice DECIMAL(10, 2)
,@page INT
,@currentDate DATETIME2(0)
,@distance NUMERIC(4, 1)
,@isFavoriteShop BIT = 0
,@currentUserNr INT = 0
,@latitude FLOAT(53) = 0
,@longitude FLOAT(53) = 0
,@itemType TINYINT = 0
,@unitRows INT OUTPUT
,@unitPages INT OUTPUT
 )
 AS
 BEGIN
SET XACT_ABORT ON
SET NOCOUNT ON

DECLARE @sql NVARCHAR(MAX)
        ,@sqlSelect NVARCHAR(MAX) = ''
        ,@sqlTempTable NVARCHAR(MAX) = '#itemSearch'
        ,@sqlCountTempTable NVARCHAR(MAX) = '#itemCount'
        ,@sqlInto NVARCHAR(MAX) = ''
        ,@sqlFrom NVARCHAR(MAX) = ''
        ,@sqlClause NVARCHAR(MAX) = ''
        ,@sqlGroup NVARCHAR(MAX) = ''
        ,@params NVARCHAR(MAX)
        ,@citySearch bit = 0
        ,@gpsSearch bit = 0
        ,@sortOrderString NVARCHAR(MAX) = 'ORDER BY IT.CREATEDATE DESC'
        ,@sortOrderString2 NVARCHAR(MAX) = ''

IF (@cityid <= 0) AND (@currentUserNr > 0) AND (@latitude = 0)
    SELECT  @cityid = CITYID
    FROM    USERINFO
    WHERE   USERNR = @currentUserNr
ELSE IF (@cityid <= 0) AND (@latitude > 0)
    SET @gpsSearch = 1
ELSE IF (@cityid > 0)
    SET @citySearch = 1



IF (@sortOrderString2 = '')
    SET @sortOrderString2 = @sortOrderString

IF (@unitItems = 0)
    SET @unitItems = 20

IF (@page <= 0)
    SET @page = 1

SET @sqlSelect =
    'SELECT     J.URLNAME
                ,IT.ITEMNR
                ,IT.USERNR
                ,IT.ShopNR
                ,IT.ITEMID
                ,IT.ITEMNAME
                ,IT.HEADER
                ,IT.DESCRIPTION
                ,IT.PRICE
                ,IT.CREATEDATE
                ,IT.ITEMSTATUS
                ,IT.CURRENCYCODE
                ,IT.CATID
                ,IT.VISIT
                ,IT.ENDDATE
                ,IT.PREAMBLE
                ,IT.SHOWDATE
                ,IT.LASTUPDATED
                ,C.CATNAME AS CATNAME

                ,J.HEADER AS ShopHEADER
                ,J.LATITUDE
                ,J.LONGITUDE
                ,R.REGIONNAME AS REGIONNAME
                ,CY.COUNTRYISO
                ,R.REGIONNR
                ,CY.COUNTRYNAME AS COUNTRYNAME
                ,CI.CITYNAME AS CITY
                ,ROW_NUMBER() OVER (' + @sortOrderString + ') AS RowNumber'

SET @sqlGroup =
    ' GROUP BY  J.URLNAME
                ,IT.ITEMNR
                ,IT.USERNR
                ,IT.ShopNR
                ,IT.ITEMID
                ,IT.ITEMNAME
                ,IT.HEADER
                ,IT.DESCRIPTION
                ,IT.PRICE
                ,IT.CREATEDATE
                ,IT.ITEMSTATUS
                ,IT.CURRENCYCODE
                ,IT.CATID
                ,IT.VISIT
                ,IT.ENDDATE
                ,IT.PREAMBLE
                ,IT.SHOWDATE
                ,IT.LASTUPDATED
                ,C.CATNAME

                ,J.HEADER
                ,J.LATITUDE
                ,J.LONGITUDE
                ,R.REGIONNAME
                ,CY.COUNTRYISO
                ,R.REGIONNR
                ,CY.COUNTRYNAME
                ,CI.CITYNAME'

SET @sqlFrom =
    ' FROM      dbo.ITEM AS IT
    INNER JOIN  dbo.Shop AS J
            ON  IT.ShopNR = J.ShopNR
    INNER JOIN  dbo.CITY AS CI
            ON  CI.CITYID = J.CITYID
    INNER JOIN  dbo.COUNTRY AS CY
            ON  CI.COUNTRYISO = CY.COUNTRYISO
    INNER JOIN  dbo.REGION AS R
            ON  CI.REGIONNR = R.REGIONNR'

    SET @sqlFrom = @sqlFrom +
        ' INNER JOIN    dbo.CATEGORY AS C
                ON  IT.CATID = C.CATID '

    SET @sqlClause =
        ' WHERE     J.ACTIVE = 1
                AND IT.ITEMSTATUS = 1
                AND IT.ENDDATE > @currentDate'      

    IF (@itemType = 1) 
        SET @sqlClause = @sqlClause +
            ' AND IT.ITEMTYPE = 1'

    IF (@catId > 0)
        SET @sqlClause = @sqlClause +
            ' AND (C.CATID = @catId OR C.PARENTCATID = @catId)'

    IF (@ShopNr > 0)
        SET @sqlClause = @sqlClause +
            ' AND IT.ShopNR = @ShopNr'

    IF (@search <> '') 
        SET @sqlClause = @sqlClause +
            ' AND ((IT.HEADER LIKE ''%' + @search + '%'') OR (IT.DESCRIPTION LIKE ''%' + @search + '%''))'

    SET @sqlInto = ' INTO ' + @sqlTempTable + ' ';

    SET @sql =  @sqlSelect +
                @sqlInto +
                @sqlFrom +
                @sqlClause +
                @sqlGroup

    SET @sql = @sql + ';

        SELECT  @unitRows = @@ROWCOUNT
                ,@unitPages = (@unitRows / @unitItems) + 1;

        SELECT  *
        FROM    ' + @sqlTempTable + ' AS IT
        WHERE   RowNumber BETWEEN (@page - 1) * @unitItems + 1 AND @unitItems * @page
        ' + @sortOrderString2 + ';

        SELECT      CATNAME
                    ,CITY
                    ,COUNT(*) AS ITEMCOUNT
                    ,GROUPING_ID(CATNAME, CITY) AS ITEMCOUNTTYPEID
        INTO        '+ @sqlCountTempTable + '
        FROM        ' + @sqlTempTable + '
        GROUP BY    GROUPING SETS
                    (
                        (CATNAME)
                        ,(CITY)
                        ,()
                    )

        SELECT      ISNULL(CATNAME, ''All Categories'') AS CATNAME
                    ,ITEMCOUNT
        FROM        '+ @sqlCountTempTable + '
        WHERE       ITEMCOUNTTYPEID IN (1, 3)
        ORDER BY    ITEMCOUNTTYPEID DESC
                    ,CATNAME

        SELECT      ISNULL(CITY, ''All Cities'') AS CITY
                    ,ITEMCOUNT
        FROM        '+ @sqlCountTempTable + '
        WHERE       ITEMCOUNTTYPEID IN (2, 3)
        ORDER BY    ITEMCOUNTTYPEID DESC
                    ,CITY';

    SELECT @params =
        N'@language nchar(2), ' +
        N'@ShopNr int, ' +
        N'@cityId int, ' +
        N'@catId int, ' +
        N'@distance numeric(4,1), ' +
        N'@currentDate datetime, ' + 
        N'@unitItems int,' + 
        N'@countryIso nchar(2),' + 
        N'@regionNr int,' + 
        N'@page int,' + 
        N'@currentUserNr int,' +
        N'@latitude float,' +
        N'@longitude float,' +
        N'@unitRows int OUTPUT,' +
        N'@unitPages int OUTPUT'

--print @sql

EXEC    sp_executesql @sql
        ,@params
        ,@language
        ,@ShopNr
        ,@cityId
        ,@catId
        ,@distance
        ,@currentDate
        ,@unitItems
        ,@countryIso
        ,@regionNr
        ,@page
        ,@currentUserNr
        ,@latitude
        ,@longitude
        ,@unitRows OUTPUT
        ,@unitPages OUTPUT
END
GO


DECLARE @unitPages INT
    ,@unitRows INT

exec Item_SearchItems_New @ShopNr=0,@unitItems=20,@catId=0,@language='',@sortOrder=0,@search=default,@countryIso='in',
@regionNr=2702259,@cityId=2702261,@maxPrice=0,@page=1,@distance=50,@currentDate='2013-02-24 19:29:50.623',@isFavoriteShop=0,
@currentUserNr=0,@latitude=0,@longitude=0,@itemType=0,@unitRows = @unitRows OUTPUT, @unitPages = @unitPages OUTPUT

SELECT  @unitPages, @unitRows
于 2013-03-10T12:26:35.717 回答
0

这是根据类别检索计数

select 'All categories' catname, count(*) catcount from itemtable
union all
select catname, count(catid) catcount
from itemtable inner join categorytable on categorytable.catid = itemtable.catid
group by catname

这是根据城市检索计数

select 'All cities' cityname, count(*) catcount from itemtable
union all
select cityname, count(catid) catcount 
from itemtable inner join shoptable on itemtable.shopid = shoptable.shopid
inner join citytable on citytable.cityid = shoptable.cityid
group by cityname
于 2013-03-02T07:54:43.517 回答