有没有更简洁的方法来运行此SQL查询?

时间:2015-03-30 14:47:49

标签: sql-server join

我加入了两张桌子。一个包含记录,另一个包含这些记录的统计信息。这是我的表格。

// ITEMS
item_id INT,
item_name NVARCHAR(MAX),
user_id INT

// STATS
stat_id INT,
item_id INT,
type TINYINT,
actions INT

我们说我有两种类型的统计数据 - 视图和编辑。我想以下列形式返回数据

item_id   item_name   item_views   item_edits
1         thing       26           32

目前,我能找到的最佳方法是将我的统计数据解析为临时表并将其连接到我的项目数据。实际上,我将两者放在表变量中,因此我不会在活动表上进行任何连接,以避免任何性能损失。这是它的外观

DECLARE @i TABLE (item_id INT, item_name NVARCHAR(MAX));
DECLARE @s TABLE (item_id INT, item_views INT, item_edits);

INSERT INTO @i
SELECT item_id, item_name FROM Items WHERE user_id = 12345;

INSERT INTO @s
SELECT item_id,SUM(item_views),SUM(item_edits) FROM (
  SELECT item_id,
    item_views = CASE ISNULL(type,0) WHEN 0 THEN SUM(actions) ELSE 0 END,
    item_edits = CASE ISNULL(type,0) WHEN 1 THEN 0 ELSE SUM(actions) END
  FROM Stats 
  WHERE item_id IN (SELECT item_id FROM @i)
  GROUP BY item_id,stat_type
) as [x] 
GROUP BY item_id

SELECT 
  t.item_id,item_name,item_views,item_edits 
FROM @i t 
INNER JOIN @s s on s.item_id = t.item_id

似乎必须有一种比这更简单的方式来加入事物?

编辑:

没有表变量,它看起来(我相信)像这样

SELECT 
  t.item_id,item_name,item_views,item_edits 
FROM Items t 
LEFT JOIN 
(SELECT item_id,SUM(item_views),SUM(item_edits) FROM (
  SELECT item_id,
    item_views = CASE ISNULL(type,0) WHEN 0 THEN SUM(actions) ELSE 0 END,
    item_edits = CASE ISNULL(type,0) WHEN 1 THEN 0 ELSE SUM(actions) END
  FROM Stats 
  WHERE item_id IN (SELECT item_id FROM Items WHERE user_id = 12345)
  GROUP BY item_id,stat_type
) as [x] 
GROUP BY item_id
) as [s] 
ON s.item_id = t.item_id
WHERE user_id = @user_id

它似乎仍然是不必要的复杂。它有三个子查询。有没有办法只使用case语句对stat行进行分组?

2 个答案:

答案 0 :(得分:1)

这可能会这样做:

SELECT  t.item_id,t.item_name, 
        SUM(CASE ISNULL(s.[type],0) WHEN 0 THEN s.actions END) AS item_views,
        SUM(CASE s.[type] WHEN 1 THEN s.actions END) AS item_edits
FROM    Items t 
        LEFT JOIN [Stats] s ON t.item_id = s.item_id
WHERE   t.[user_id] = @user_id
GROUP BY t.item_id,t.item_name;

答案 1 :(得分:0)

有很多不必要的代码。试试这个:

SELECT t.item_id, t.item_name, iv.item_views, ie.item_edits 
FROM Items t 
OUTER APPLY(SELECT SUM(actions) AS item_views FROM STATS s WHERE s.item_id = t.item_id AND ISNULL(type, 0) = 0) iv
OUTER APPLY(SELECT SUM(actions) AS item_edits FROM STATS s WHERE s.item_id = t.item_id AND ISNULL(type, 0) = 1) ie