我有一段代码正在寻找不同数量的小桶,已标记的不同小桶的数量和未标记的小桶的数量,到目前为止,我的了解是:
with CTE as
(select UID_KEG, IS_TAGGED, movement_date
from MOVEMENT M
inner join Keg on M.UID_Keg = Keg.Unique_ID
where DATEPART(year,Movement_date) = '2019'
and UID_MOVEMENT_TYPE = 1
)
select COUNT(Distinct CTE.UID_KEG) as 'Kegs', datepart(week,movement_date)
as 'Week number',
SUM(case when Is_Tagged = 1 then 1 end) as 'tagged',
SUM(case when Is_Tagged = 0 then 1 end) as 'untagged'
from CTE
group by datepart(week,movement_date)
order by [Week number] asc
它会立即返回不同数量的小桶,但是带标签的和未带标签的数字是错误的,我只能假设是因为它正在计数重复的小桶。 有人可以建议我如何解决这个问题,还是只依靠不同的小桶?
答案 0 :(得分:0)
如果您从计数中除去Distinct,则未开发和已开发的总和应等于总数(如果它是二进制0或1)。这表明您有重复的UID_KEG值。花一些时间来了解原因。问题的部分原因是您似乎不太了解数据集的形状。
花一些时间查看数据以了解是否存在重复项(为什么?是由联接引起的,还是它们在基础数据中?),请查看它们是否可以显示为已标记和未标记。< / p>
编辑:针对您的评论。如果可以对它们进行两次扫描,则必须假设如果当天的任何UID_KEG的Is_Tagged = 1,那么所有带有该UID_KEG的小桶都会被标记。
在这种情况下,您将不得不修改代码以使用此假设。
WITH CTE
AS (
SELECT UID_KEG
,IS_TAGGED
,movement_date
FROM MOVEMENT M
INNER JOIN Keg ON M.UID_Keg = Keg.Unique_ID
WHERE DATEPART(year, Movement_date) = '2019'
AND UID_MOVEMENT_TYPE = 1
)
SELECT CTE.UID_KEG AS 'Kegs'
,datepart(week, movement_date) AS 'Week number'
,MAX(Is_Tagged) AS 'tagged'
FROM CTE
GROUP BY CTE.UID_KEG
,datepart(week, movement_date)
ORDER BY [Week number] ASC
此代码可能并不完美,我无法对其进行测试,但是它应该为您提供每一天每一桶的完整列表,以及该桶是否至少被标记为已标记一次,如果没有,标记为已标记。
这里最重要的是每天消除小桶的重复,然后才可以计算。
我对CTE不太满意,但是您需要将一个级别汇总到每日级别,现在您将能够计算不同数量的小桶以及标记和未标记的小桶。
希望如此。
编辑:这是应该正常工作的子查询
SELECT [Week number]
,count(1) [numKegs]
,sum(tagged) [numTagged]
FROM (
SELECT UID_KEG AS 'Kegs'
,datepart(week, movement_date) AS 'Week number'
,MAX(IS_TAGGED) AS 'tagged'
FROM MOVEMENT M
INNER JOIN Keg ON M.UID_Keg = Keg.Unique_ID
WHERE DATEPART(year, Movement_date) = '2019'
AND UID_MOVEMENT_TYPE = 1
GROUP BY UID_KEG
,datepart(week, movement_date)
) kegdailylevel
GROUP BY [Week number]
ORDER BY [Week number] ASC
答案 1 :(得分:0)
您想要使用COUNT(DISTINCT)
进行条件聚合。那应该是:
SELECT COUNT(DISTINCT CTE.UID_KEG) as Kegs,
datepart(week, movement_date) as Week_number,
COUNT(DISTINCT CASE WHEN Is_Tagged = 1 THEN CTE.UID_KEG END) as tagged,
COUNT(DISTINCT(CASE WHEN Is_Tagged = 0 THEN CTE.UID_KEG END) as untagged
FROM CTE
GROUP BY datepart(week, movement_date)
ORDER BY MIN(movement_date);
注意:
year()
和星期,尤其是因为您不是从一年中选择数据。