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 改进,参考,任何东西。

几种方法。一种是简单地执行最后一个操作:

Fiddle

另请注意:我调整了原来的 SQL,因为 c.TimeSlotsCount 不存在。你没有ctable/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;