选择查询逻辑sql服务器

时间:2019-07-02 05:27:20

标签: sql-server

我在下表中有数据,

Emp_ID      Country_Code
101          AE
101          AE
102          AE
102          SG
102          AE
103          AE
103          AE
103          SG
103          SG
104          AE
104          AE
104          SG
104          SG
104          HK

如果我根据Emp_Id和国家/地区分组,我可以获得以下结果集,

Emp_ID        Country_Code       count
101           AE                  2
102           AE                  2
102           SG                  1
103           AE                  2
103           SG                  2
104           AE                  2
104           HK                  1
104           SG                  2

我在此结果集中有4种情况,

  1. 情况1:如果我的Emp_Id只有一个Country_Code,则无需 更新该Emp_Id的表。 (例如Emp_Id = 101)
  2. 情况2:如果 Country_Code计数相同(在我们的示例中为emp_id:103),我们需要 将该emp_id的country_code更新为“空”
  3. 情况3:如果“国家/地区代码”计数不同(本例中为emp_id:102), 需要为此Emp_Id更新最高国家/地区计数Country_Code。
  4. 情况4:如果Country_code计数不同(在我们的示例中为emp_id:104),并且 最高计数也大于1,我们需要将country_code更新为null 那个emp_id。

预期产量

Emp_ID      Country_Code
101          AE
101          AE
102          AE
102          AE
102          AE
103          NULL
103          NULL
103          NULL
103          NULL
104          NULL
104          NULL
104          NULL
104          NULL
104          NULL

1 个答案:

答案 0 :(得分:1)

以下查询应执行您想要的操作:

CREATE TABLE #emp (Emp_ID INT,Country_Code VARCHAR(10))
INSERT INTO #emp VALUES
(101,'AE'),(101,'AE'),  -- Case 1
(102,'AE'),(102,'SG'),(102,'AE'),   -- Case 3
(103,'AE'),(103,'AE'),(103,'SG'),(103,'SG'),    -- Case 2
(104,'IN'), -- Case 1
(105,'AB'),(105,'AB'),(105,'BC'),(105,'BC'),(105,'CD'),(105,'CD'),  -- Case 2
(106,'CD'),(106,'IJ'),(106,'IJ'),   -- Case 3
(107,'AA'),(107,'BB'),(107,'CC'),   -- Case 2
(108,'AE'),(108,'AE'),(108,'SG'),(108,'SG'),(108,'HK'), -- Case 4
(109,'ZZ'),(109,'ZZ'),(109,'YY'),(109,'XX') -- Case 3

UPDATE t
SET Country_Code = CASE WHEN cnt = 1 AND dst_cnt = 1 THEN Country_Code  -- Case 1
                        WHEN cnt > 1 AND dst_cnt = 1 THEN NULL  -- Case 2
                        WHEN cnt > 1 AND dst_cnt <> 1 THEN (SELECT TOP 1 CASE WHEN cnt = lead(cnt) OVER( ORDER BY (cnt)) THEN NULL ELSE Country_Code END 
                                                            FROM ( SELECT Country_Code, RANK() OVER (ORDER BY COUNT(*) DESC) cnt FROM #emp WHERE Emp_ID = t.Emp_ID
                                                                   GROUP BY Country_Code ) A WHERE cnt = 1) END -- Case 3 & 4  
FROM #emp t
JOIN (
    SELECT Emp_ID
        ,COUNT(cnt) AS cnt
        ,COUNT(DISTINCT cnt) AS dst_cnt
    FROM (SELECT Emp_ID
            ,Country_Code
            ,COUNT(Country_Code) AS cnt
        FROM #emp
        GROUP BY Emp_ID,Country_Code) a
    GROUP BY Emp_ID 
    ) b ON t.Emp_ID = b.Emp_ID

SELECT * FROM #emp
ORDER BY Emp_ID