使用asp.net mvc应用程序和c#。我们正在开发搜索页面。
更新了我的答案。请在下面查看我自己的答案并建议
遗憾的是,select into无法在sql azure http://blogs.msdn.com/b/sqlazure/archive/2010/05/04/10007212.aspx
中使用帮帮我
我有以下表格来显示我的项目搜索结果
项目表
购物台
城市表
类别表
这是我的搜索查询,它给出了给定条件的分页结果
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中添加了新的更改。现在,搜索界面会显示如下所示的内容
第一个结果集 - >假设总共发现了230条记录
在小提琴中看到的搜索结果
第二个结果集 - >不同类别&从230条记录算起
CatId,CatName,TotalCountInSearch
Ex:1本书25& 2体育43& 8其他52。 显示我可以在UI中显示如下
第三个结果集 - >不同城市&从230条记录算起
CityId,CityName,TotalCountInSearch
用于在UI中显示以下
如何检索这些计数和名称,如所有类别,书籍, allcities等?欢迎任何帮助或建议。
Click and View SQL Fiddle here
我想根据搜索条件获得这些计数。希望从我的程序
中将其作为另一个结果集进行检索主要更新:
我在此处上传了所有架构和实际动态查询 https://github.com/Padayappa/SQLProblem/blob/master/PaginationIssue
答案 0 :(得分: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示例。
答案 1 :(得分: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
答案 2 :(得分:1)
最后我创建了以下SP并解决了问题。
请告诉我这是正确的方法吗?
我使用了临时表,分组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
答案 3 :(得分: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