SQL 插入重复项
SQL Insert into duplicates
我的代码如下:
SELECT DISTINCT
lc.locationName,
(SELECT SUM(c.TimeSlotsCount) FROM Schedule s
WHERE s.ServiceId = sv.ServiceId
AND sv.LocationId = lc.LocationId
AND sv.ServiceName LIKE '%TYPE_ONE%'
AND s.Date >= GETDATE()) AS TYPE_ONE_COUNT,
(SELECT SUM(c.TimeSlotsCount) FROM Schedule s
WHERE s.ServiceId = sv.ServiceId
AND sv.LocationId = lc.LocationId
AND sv.ServiceName LIKE '%TYPE_TWO%'
AND s.Date >= GETDATE()) AS TYPE_TWO_COUNT,
(SELECT SUM(c.TimeSlotsCount) FROM Schedule s
WHERE s.ServiceId = sv.ServiceId
AND sv.LocationId = lc.LocationId
AND sv.ServiceName LIKE '%TYPE_THREE%'
AND s.Date >= GETDATE()) AS TYPE_THREE_COUNT
FROM
Schedule AS sc WITH (NOLOCK) --/*This table has timeslotscount, serviceid*/
LEFT JOIN
ServiceList AS sv ON sv.ServiceId = sc.ServiceId --/*This table has locationid, serviceid(type1/type2/type3 depending on location[all locations has type1/2/3])*/
LEFT JOIN
Location AS lc ON sv.LocationId = lc.LocationId --/*This table has locationid, locationname*/
我应该解释一下 SUM()
,日程表上有不同的日期,例如
serviceId | dd/mm/yyyy hh:mm:ss | count for this day
我想获得今天之后“serviceId”的所有“计数”,因此 'date >= GETDATE()'
基本上我希望 table 看起来像这样:
LOCATION | TYPE_ONE_COUNT | TYPE_TWO_COUNT | TYPE_THREE_COUNT
我能够获取值,但我是这样获取的:
LocationOne | 12 | 0 | 0
LocationOne | 0 | 12 | 0
LocationOne | 0 | 0 | 34
LocationTwo | 1 | 0 | 0
LocationTwo | 0 | 42 | 0
LocationTwo | 0 | 0 | 9
而我想显示为
LocationOne | 12 | 12 | 34
LocationTwo | 1 | 42 | 9
感谢您提供的所有帮助。我哪里错了,syntax/performance 改进,参考,任何东西。
几种方法。一种是简单地执行最后一个操作:
另请注意:我调整了原来的 SQL,因为 c.TimeSlotsCount
不存在。你没有c
table/alias。我将 TimeSlotsCount
添加到 Schedule
table。根据 TimeSlotsCount
.
的实际来源,根据需要进行调整
WITH cte AS (
Your above SQL from the question, without semicolon
)
SELECT locationName
, SUM(TYPE_ONE_COUNT) AS TYPE_ONE_COUNT
, SUM(TYPE_TWO_COUNT) AS TYPE_TWO_COUNT
, SUM(TYPE_THREE_COUNT) AS TYPE_THREE_COUNT
FROM cte
GROUP BY locationName
;
我们也可以在原始 SQL 中做一个稍微不同的 SUM,没有 DISTINCT
而有 GROUP BY
,避免额外的 CTE 项。
但从逻辑上讲,这些是相同的。
最终 SQL,直接使用您的 SQL:
WITH cte AS (
SELECT DISTINCT
lc.locationName,
(SELECT SUM(s.TimeSlotsCount) FROM Schedule s
WHERE s.ServiceId = sv.ServiceId
AND sv.LocationId = lc.LocationId
AND sv.ServiceName LIKE '%TYPE_ONE%'
AND s.Date >= GETDATE()) AS TYPE_ONE_COUNT,
(SELECT SUM(s.TimeSlotsCount) FROM Schedule s
WHERE s.ServiceId = sv.ServiceId
AND sv.LocationId = lc.LocationId
AND sv.ServiceName LIKE '%TYPE_TWO%'
AND s.Date >= GETDATE()) AS TYPE_TWO_COUNT,
(SELECT SUM(s.TimeSlotsCount) FROM Schedule s
WHERE s.ServiceId = sv.ServiceId
AND sv.LocationId = lc.LocationId
AND sv.ServiceName LIKE '%TYPE_THREE%'
AND s.Date >= GETDATE()) AS TYPE_THREE_COUNT
FROM
Schedule AS sc WITH (NOLOCK) --/*This table has timeslotscount, serviceid*/
LEFT JOIN
ServiceList AS sv ON sv.ServiceId = sc.ServiceId --/*This table has locationid, serviceid(type1/type2/type3 depending on location[all locations has type1/2/3])*/
LEFT JOIN
Location AS lc ON sv.LocationId = lc.LocationId --/*This table has locationid, locationname*/
)
SELECT locationName
, SUM(TYPE_ONE_COUNT) AS TYPE_ONE_COUNT
, SUM(TYPE_TWO_COUNT) AS TYPE_TWO_COUNT
, SUM(TYPE_THREE_COUNT) AS TYPE_THREE_COUNT
FROM cte
GROUP BY locationName
;
您可以使用条件聚合来完成:
SELECT lc.locationName,
SUM(CASE WHEN sv.ServiceName LIKE '%TYPE_ONE%' THEN sc.TimeSlotsCount ELSE 0 END) AS TYPE_ONE_COUNT,
SUM(CASE WHEN sv.ServiceName LIKE '%TYPE_TWO%' THEN sc.TimeSlotsCount ELSE 0 END) AS TYPE_TWO_COUNT,
SUM(CASE WHEN sv.ServiceName LIKE '%TYPE_THREE%' THEN sc.TimeSlotsCount ELSE 0 END) AS TYPE_THREE_COUNT
FROM Location AS lc
LEFT JOIN ServiceList AS sv ON sv.LocationId = lc.LocationId
LEFT JOIN Schedule AS sc ON sv.ServiceId = sc.ServiceId AND sc.Date >= GETDATE()
GROUP BY lc.LocationId, lc.locationName;
我的代码如下:
SELECT DISTINCT
lc.locationName,
(SELECT SUM(c.TimeSlotsCount) FROM Schedule s
WHERE s.ServiceId = sv.ServiceId
AND sv.LocationId = lc.LocationId
AND sv.ServiceName LIKE '%TYPE_ONE%'
AND s.Date >= GETDATE()) AS TYPE_ONE_COUNT,
(SELECT SUM(c.TimeSlotsCount) FROM Schedule s
WHERE s.ServiceId = sv.ServiceId
AND sv.LocationId = lc.LocationId
AND sv.ServiceName LIKE '%TYPE_TWO%'
AND s.Date >= GETDATE()) AS TYPE_TWO_COUNT,
(SELECT SUM(c.TimeSlotsCount) FROM Schedule s
WHERE s.ServiceId = sv.ServiceId
AND sv.LocationId = lc.LocationId
AND sv.ServiceName LIKE '%TYPE_THREE%'
AND s.Date >= GETDATE()) AS TYPE_THREE_COUNT
FROM
Schedule AS sc WITH (NOLOCK) --/*This table has timeslotscount, serviceid*/
LEFT JOIN
ServiceList AS sv ON sv.ServiceId = sc.ServiceId --/*This table has locationid, serviceid(type1/type2/type3 depending on location[all locations has type1/2/3])*/
LEFT JOIN
Location AS lc ON sv.LocationId = lc.LocationId --/*This table has locationid, locationname*/
我应该解释一下 SUM()
,日程表上有不同的日期,例如
serviceId | dd/mm/yyyy hh:mm:ss | count for this day
我想获得今天之后“serviceId”的所有“计数”,因此 'date >= GETDATE()'
基本上我希望 table 看起来像这样:
LOCATION | TYPE_ONE_COUNT | TYPE_TWO_COUNT | TYPE_THREE_COUNT
我能够获取值,但我是这样获取的:
LocationOne | 12 | 0 | 0
LocationOne | 0 | 12 | 0
LocationOne | 0 | 0 | 34
LocationTwo | 1 | 0 | 0
LocationTwo | 0 | 42 | 0
LocationTwo | 0 | 0 | 9
而我想显示为
LocationOne | 12 | 12 | 34
LocationTwo | 1 | 42 | 9
感谢您提供的所有帮助。我哪里错了,syntax/performance 改进,参考,任何东西。
几种方法。一种是简单地执行最后一个操作:
另请注意:我调整了原来的 SQL,因为 c.TimeSlotsCount
不存在。你没有c
table/alias。我将 TimeSlotsCount
添加到 Schedule
table。根据 TimeSlotsCount
.
WITH cte AS (
Your above SQL from the question, without semicolon
)
SELECT locationName
, SUM(TYPE_ONE_COUNT) AS TYPE_ONE_COUNT
, SUM(TYPE_TWO_COUNT) AS TYPE_TWO_COUNT
, SUM(TYPE_THREE_COUNT) AS TYPE_THREE_COUNT
FROM cte
GROUP BY locationName
;
我们也可以在原始 SQL 中做一个稍微不同的 SUM,没有 DISTINCT
而有 GROUP BY
,避免额外的 CTE 项。
但从逻辑上讲,这些是相同的。
最终 SQL,直接使用您的 SQL:
WITH cte AS (
SELECT DISTINCT
lc.locationName,
(SELECT SUM(s.TimeSlotsCount) FROM Schedule s
WHERE s.ServiceId = sv.ServiceId
AND sv.LocationId = lc.LocationId
AND sv.ServiceName LIKE '%TYPE_ONE%'
AND s.Date >= GETDATE()) AS TYPE_ONE_COUNT,
(SELECT SUM(s.TimeSlotsCount) FROM Schedule s
WHERE s.ServiceId = sv.ServiceId
AND sv.LocationId = lc.LocationId
AND sv.ServiceName LIKE '%TYPE_TWO%'
AND s.Date >= GETDATE()) AS TYPE_TWO_COUNT,
(SELECT SUM(s.TimeSlotsCount) FROM Schedule s
WHERE s.ServiceId = sv.ServiceId
AND sv.LocationId = lc.LocationId
AND sv.ServiceName LIKE '%TYPE_THREE%'
AND s.Date >= GETDATE()) AS TYPE_THREE_COUNT
FROM
Schedule AS sc WITH (NOLOCK) --/*This table has timeslotscount, serviceid*/
LEFT JOIN
ServiceList AS sv ON sv.ServiceId = sc.ServiceId --/*This table has locationid, serviceid(type1/type2/type3 depending on location[all locations has type1/2/3])*/
LEFT JOIN
Location AS lc ON sv.LocationId = lc.LocationId --/*This table has locationid, locationname*/
)
SELECT locationName
, SUM(TYPE_ONE_COUNT) AS TYPE_ONE_COUNT
, SUM(TYPE_TWO_COUNT) AS TYPE_TWO_COUNT
, SUM(TYPE_THREE_COUNT) AS TYPE_THREE_COUNT
FROM cte
GROUP BY locationName
;
您可以使用条件聚合来完成:
SELECT lc.locationName,
SUM(CASE WHEN sv.ServiceName LIKE '%TYPE_ONE%' THEN sc.TimeSlotsCount ELSE 0 END) AS TYPE_ONE_COUNT,
SUM(CASE WHEN sv.ServiceName LIKE '%TYPE_TWO%' THEN sc.TimeSlotsCount ELSE 0 END) AS TYPE_TWO_COUNT,
SUM(CASE WHEN sv.ServiceName LIKE '%TYPE_THREE%' THEN sc.TimeSlotsCount ELSE 0 END) AS TYPE_THREE_COUNT
FROM Location AS lc
LEFT JOIN ServiceList AS sv ON sv.LocationId = lc.LocationId
LEFT JOIN Schedule AS sc ON sv.ServiceId = sc.ServiceId AND sc.Date >= GETDATE()
GROUP BY lc.LocationId, lc.locationName;