我有可存储每日内容选择的数据。 每天都有所不同。
当我选择超过一天时,我需要退回所有日子都相同的项目。
我尝试过这样的事情:
SELECT * FROM
(
SELECT
( -- For count
SELECT COUNT(recipeId) AS [Count]
FROM DailyContentDish
WHERE
(
(weekDayId=@mon OR @mon IS NULL) OR
(weekDayId=@tue OR @tue IS NULL) OR
(weekDayId=@wed OR @wed IS NULL) OR
(weekDayId=@thu OR @thu IS NULL) OR
(weekDayId=@fri OR @fri IS NULL) OR
(weekDayId=@sat OR @sat IS NULL) OR
(weekDayId=@sun OR @sun IS NULL)
)
GROUP BY DailyContentDish.recipeId
) AS cnt,
-- End for count
DailyContentDish.dailyContentDishId,
DailyContentDish.recipeId AS Rec,
title,
150 AS calories,
defaultSmallImagePath,
activePreparationTime + passivePreparationTime AS overallPreparationTime,
CAST(
CASE WHEN EXISTS
(
SELECT DailyContentDishFavourite.dailyContentDishFavouriteId
FROM DailyContentDishFavourite
WHERE DailyContentDishFavourite.dailyContentDishId = DailyContentDish.dailyContentDishId
)
THEN 1
ELSE 0
END
AS BIT) AS isFavouriteWhenGeneratingMenu
FROM DailyContentDish
LEFT OUTER JOIN
RecipesTranslations ON RecipesTranslations.recipeId = DailyContentDish.recipeId
LEFT OUTER JOIN
RecipeAdditionalInformation ON RecipeAdditionalInformation.recipeId = DailyContentDish.recipeId
WHERE
isEnabled = 1 AND
mealId=@mealId AND
(
weekDayId=@mon OR
weekDayId=@tue OR
weekDayId=@wed OR
weekDayId=@thu OR
weekDayId=@fri OR
weekDayId=@sat OR
weekDayId=@sun
)
) p
WHERE p.cnt = @daysCount
问题是,应该返回count的嵌套select会为所有行返回它,而不仅仅是一个条目(每一行)。 由于输入了recipeId的条目多了一次,我想知道它们输入了多少次。
SELECT
( -- For count
SELECT COUNT(recipeId) AS [Count]
FROM DailyContentDish
WHERE
(
(weekDayId=@mon OR @mon IS NULL) OR
(weekDayId=@tue OR @tue IS NULL) OR
(weekDayId=@wed OR @wed IS NULL) OR
(weekDayId=@thu OR @thu IS NULL) OR
(weekDayId=@fri OR @fri IS NULL) OR
(weekDayId=@sat OR @sat IS NULL) OR
(weekDayId=@sun OR @sun IS NULL)
) AND Something should be here (I guess)
GROUP BY DailyContentDish.recipeId
) AS cnt,
-- End for count
此部分应为我选择的每一行返回COUNT个条目 - 但它会将所有条目的COUNT重新归还。
或者我应该采取不同的方式。 任何提示都非常感谢。
我正在使用MS SQL Server 2008
编辑: 这是整个存储过程:
@userId int,
@languageId int,
@mealId int,
@mon int,
@tue int,
@wed int,
@thu int,
@fri int,
@sat int,
@sun int,
@orderBy nvarchar(2),
@pageSize int,
@startRowIndex int
AS
BEGIN
SET NOCOUNT ON;
DECLARE @daysCount int
SET @daysCount = 0
IF (@mon IS NOT NULL)
BEGIN
SET @daysCount = @daysCount+1
END
IF (@tue IS NOT NULL)
BEGIN
SET @daysCount = @daysCount+1
END
IF (@wed IS NOT NULL)
BEGIN
SET @daysCount = @daysCount+1
END
IF (@thu IS NOT NULL)
BEGIN
SET @daysCount = @daysCount+1
END
IF (@fri IS NOT NULL)
BEGIN
SET @daysCount = @daysCount+1
END
IF (@sat IS NOT NULL)
BEGIN
SET @daysCount = @daysCount+1
END
IF (@sun IS NOT NULL)
BEGIN
SET @daysCount = @daysCount+1
END
-- Insert statements for procedure here
SELECT *
FROM (
SELECT
(
SELECT [Count] = COUNT(recipeId)
FROM dbo.DailyContentDish d
WHERE
(
ISNULL(@mon, weekDayId) = weekDayId OR
ISNULL(@tue, weekDayId) = weekDayId OR
ISNULL(@wed, weekDayId) = weekDayId OR
ISNULL(@thu, weekDayId) = weekDayId OR
ISNULL(@fri, weekDayId) = weekDayId OR
ISNULL(@sat, weekDayId) = weekDayId OR
ISNULL(@sun, weekDayId) = weekDayId
)
GROUP BY d.recipeId
) AS cnt,
d.dailyContentDishId,
d.recipeId AS Rec,
title,
150 AS calories,
defaultSmallImagePath,
activePreparationTime + passivePreparationTime AS overallPreparationTime,
CASE WHEN d2.dailyContentDishId IS NULL THEN 1 ELSE 0 END AS isFavouriteWhenGeneratingMenu
FROM dbo.DailyContentDish d
LEFT JOIN dbo.RecipesTranslations r ON r.recipeId = d.recipeId
LEFT JOIN dbo.RecipeAdditionalInformation t ON t.recipeId = d.recipeId
LEFT JOIN dbo.DailyContentDishFavourite d2 ON d.dailyContentDishId = d2.dailyContentDishId
WHERE isEnabled = 1
AND mealId = @mealId
AND (
weekDayId = @mon OR
weekDayId = @tue OR
weekDayId = @wed OR
weekDayId = @thu OR
weekDayId = @fri OR
weekDayId = @sat OR
weekDayId = @sun
)
) p
WHERE p.cnt = @daysCount
Edit1:我上传了图表:
以下是样本数据(用餐ID = 1,也在表格中选择),说明: - ID为125的食谱将在星期一(weekDayId = 1)和星期六(weekDayId = 7)出现。因此,如果我只选择星期一,或者如果我只选择星期六,或者如果我选择星期一和星期六,则必须返回此食谱。如果我也选择任何其他日子,则不会返回ithis记录。 - 选择周日1,6和7(周一,周六,周日)时,必须返回ID为105的食谱。与上述相同,如果选择任何其他日期,则不会返回此记录。
答案 0 :(得分:2)
这可能对您有帮助 -
ALTER PROCEDURE dbo.usp_GetDailyContentDish
@userId INT,
@languageId INT,
@mealId INT,
@mon INT,
@tue INT,
@wed INT,
@thu INT,
@fri INT,
@sat INT,
@sun INT,
@orderBy NVARCHAR(2),
@pageSize INT,
@startRowIndex INT
AS BEGIN
SET NOCOUNT ON;
DECLARE @daysCount INT
SELECT @daysCount =
CASE WHEN @mon IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN @tue IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN @wed IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN @thu IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN @fri IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN @sat IS NOT NULL THEN 1 ELSE 0 END +
CASE WHEN @sun IS NOT NULL THEN 1 ELSE 0 END
SELECT
Rec
, calories
, overallPreparationTime
, isFavouriteWhenGeneratingMenu
FROM (
SELECT
(
SELECT [Count] = COUNT(d3.recipeId)
FROM dbo.DailyContentDish d3
WHERE
(
ISNULL(@mon, weekDayId) = weekDayId OR
ISNULL(@tue, weekDayId) = weekDayId OR
ISNULL(@wed, weekDayId) = weekDayId OR
ISNULL(@thu, weekDayId) = weekDayId OR
ISNULL(@fri, weekDayId) = weekDayId OR
ISNULL(@sat, weekDayId) = weekDayId OR
ISNULL(@sun, weekDayId) = weekDayId
) AND d3.recipeId = d.recipeId
GROUP BY d3.recipeId
) AS cnt,
d.dailyContentDishId,
d.recipeId AS Rec,
title,
150 AS calories,
defaultSmallImagePath,
activePreparationTime + passivePreparationTime AS overallPreparationTime,
CASE WHEN d2.dailyContentDishId IS NULL THEN 1 ELSE 0 END AS isFavouriteWhenGeneratingMenu
FROM dbo.DailyContentDish d
LEFT JOIN dbo.RecipesTranslations r ON r.recipeId = d.recipeId
LEFT JOIN dbo.RecipeAdditionalInformation t ON t.recipeId = d.recipeId
LEFT JOIN dbo.DailyContentDishFavourite d2 ON d.dailyContentDishId = d2.dailyContentDishId
WHERE isEnabled = 1
AND mealId = @mealId
AND (
weekDayId = @mon OR
weekDayId = @tue OR
weekDayId = @wed OR
weekDayId = @thu OR
weekDayId = @fri OR
weekDayId = @sat OR
weekDayId = @sun
)
) p
WHERE p.cnt = @daysCount
END
小型顶部:
此:
AND (
weekDayId = @mon OR
weekDayId = @tue OR
weekDayId = @wed OR
weekDayId = @thu OR
weekDayId = @fri OR
weekDayId = @sat OR
weekDayId = @sun
)
可能优化:
weekDayId % @weekDay = 0
如果@mon,@ tue 不为空且包含1,2,......
答案 1 :(得分:2)
SELECT *
FROM (
SELECT
( -- For count
SELECT COUNT(d.recipeId) AS [Count]
FROM DailyContentDish d
WHERE (
ISNULL(@amon, d.weekDayId) = d.weekDayId OR
ISNULL(@tue, d.weekDayId) = d.weekDayId OR
ISNULL(@wed, d.weekDayId) = d.weekDayId OR
ISNULL(@thu, d.weekDayId) = d.weekDayId OR
ISNULL(@fri, d.weekDayId) = d.weekDayId OR
ISNULL(@sat, d.weekDayId) = d.weekDayId OR
ISNULL(@sun, d.weekDayId) = d.weekDayId
) AND d.recipeId = DailyContentDish.recipeId
GROUP BY d.recipeId
) AS cnt,
-- End for count
DailyContentDish.dailyContentDishId,
DailyContentDish.recipeId AS Rec,
title,
150 AS calories,
defaultSmallImagePath,
activePreparationTime + passivePreparationTime AS overallPreparationTime,
CAST(
CASE WHEN EXISTS
(
SELECT DailyContentDishFavourite.dailyContentDishFavouriteId
FROM DailyContentDishFavourite
WHERE DailyContentDishFavourite.dailyContentDishId = DailyContentDish.dailyContentDishId
)
THEN 1
ELSE 0
END
AS BIT) AS isFavouriteWhenGeneratingMenu
FROM DailyContentDish
LEFT OUTER JOIN
RecipesTranslations ON RecipesTranslations.recipeId = DailyContentDish.recipeId
LEFT OUTER JOIN
RecipeAdditionalInformation ON RecipeAdditionalInformation.recipeId = DailyContentDish.recipeId
WHERE
isEnabled = 1 AND
mealId=@mealId AND
(
weekDayId=@mon OR
weekDayId=@tue OR
weekDayId=@wed OR
weekDayId=@thu OR
weekDayId=@fri OR
weekDayId=@sat OR
weekDayId=@sun
)
) p
WHERE p.cnt = @daysCount
更新21.05.2013(已添加演示)
IF OBJECT_ID('tempdb.dbo.#weekDays') IS NOT NULL DROP TABLE dbo.#weekDays
SELECT weekDayId
INTO dbo.#weekDays
FROM(VALUES(@mon),
(@tue),
(@wed),
(@thu),
(@fri),
(@sat),
(@sun))x(weekDayId)
WHERE weekDayId IS NOT NULL
CREATE UNIQUE CLUSTERED INDEX x ON dbo.#weekDays(weekDayId)
SELECT d.dailyContentDishId,
d.recipeId AS Rec,
title,
150 AS calories,
defaultSmallImagePath,
activePreparationTime + passivePreparationTime AS overallPreparationTime,
CASE WHEN f.dailyContentDishId IS NULL THEN 1 ELSE 0 END AS isFavouriteWhenGeneratingMen
FROM DailyContentDish d
LEFT JOIN RecipesTranslations ON RecipesTranslations.recipeId = d.recipeId
LEFT JOIN RecipeAdditionalInformation ON RecipeAdditionalInformation.recipeId = d.recipeId
LEFT JOIN dbo.DailyContentDishFavourite f ON d.dailyContentDishId = f.dailyContentDishId
WHERE d.isEnabled = 1 AND d.mealId = @mealId
AND NOT EXISTS(
SELECT d3.weekDayId
FROM dbo.#weekDays d3
EXCEPT
SELECT d2.WeekDayId
FROM DailyContentDish d2
WHERE d.recipeId = d2.recipeId
AND d2.isEnabled = 1 AND d2.mealId = @mealId
)
上的简单演示
答案 2 :(得分:1)
只有当天(和用餐)相同的膳食应该是 返回
缺少的是外部查询与内部查询中的计数计算的相关性。即以下内容:
( DC1.WeekDayId In( @Mon, @Tue, @Wed, @Thu, @Fri, @Sat, @Sun )
Or Coalesce( @Mon, @Tue, @Wed, @Thu, @Fri, @Sat, @Sun ) Is Null )
And DC1.MealId = DC.MealId
您需要对至少一个表进行别名才能实现此目的。通常,如果在内部和外部查询上对表进行别名,则更容易阅读。缺少的另一个项目是每天的七个变量代表刻度("选择这一天")而不是一天本身。如果我们改变它,它会使查询更简单。
Select @Mon = Case When @Mon Is Not Null Then 1 End
, @Tue = Case When @Tue Is Not Null Then 2 End
, @Wed = Case When @Wed Is Not Null Then 3 End
, @Thu = Case When @Thu Is Not Null Then 4 End
, @Fri = Case When @Fri Is Not Null Then 5 End
, @Sat = Case When @Sat Is Not Null Then 6 End
, @Sun = Case When @Sun Is Not Null Then 7 End;
Select Count(*) Over() As CountOfResults
, (
Select Count(*)
From DailyContentDish As DC1
Where DC1.weekDayId = DC.weekDayId
) As CountOfDishesOnDay
, (
Select Count(Distinct mealId)
From DailyContentDish As DC1
Where DC1.weekDayId = DC.weekDayId
) As CountOfMeals
, DC.DailyContentDishId
, DC.RecipeId As Rec
, Title
, 150 As Calories
, DefaultsMallImagePath
, ActivePreparationTime
+ PassivePreparationTime As OverallPreparationTime
, Cast (
Case
When Exists (
Select 1
From DailyContentDishFavourite As DF1
Where DF1.DailyContentDishId = DC.DailyContentDishId
) Then 1
Else 0
End
As Bit) As IsFavouriteWhenGeneratingMenu
From DailyContentDish As DC
Left Join RecipesTranslations As RT
On RT.RecipeId = DC.RecipeId
Left Join RecipeAdditionalInformation As RA
On RA.RecipeId = DC.RecipeId
Where DC.IsEnabled = 1
And DC.MealId=@MealId
And DC.WeekDayId In( @Mon, @Tue, @Wed, @Thu, @Fri, @Sat, @Sun )
<强>加成强>
如果每日变量应该代表每天返回的结果计数(例如,如果@Mon = 2
,那么我们应该在星期一返回两行),然后你可以这样做:
Declare @DailyParameters Table
(
DayCount int not null
, DayOfWeek int not null
)
Insert @DailyParameters( DayCount, DayOfWeek )
Select Z.Cnt, Z.DayOfWeek
From (
Select @Mon As Cnt, 1 As DayOfWeek
Union All Select @Tue, 2
Union All Select @Wed, 3
Union All Select @Thu, 4
Union All Select @Fri, 5
Union All Select @Sat, 6
Union All Select @Sun, 7
) As Z
Where Z.Cnt Is Not Null
然后Where子句会改为:
Where DC.IsEnabled = 1
And DC.MealId = @MealId
And DC.WeekDayId In( Select DayOfWeek From @DailyParameters )
And (
Select Count(*)
From DailyContentDish As DC1
Where DC1.weekDayId = DC.weekDayId
) = (
Select D1.DayCount
From @DailyParameters As D1
Where D1.DayOfWeek = DC.weekDayId
)
答案 3 :(得分:0)
“由于输入了recipeId的条目多了一次,我想知道它们输入了多少次。”
基于这个陈述,我只会将OVER子句与COUNT一起使用。
类似的东西:
SELECT
COUNT(*) OVER (PARTITION BY recipeId) AS 'cnt'
FROM DailyContentDish
我需要有关表的更多详细信息以及输出应该是什么,以便提供更多详细信息。
以下是2008年OVER条款的更多信息:http://msdn.microsoft.com/en-us/library/ms189461(v=sql.105).aspx