根据可用性从多行中选择一行

时间:2018-03-16 05:52:59

标签: sql sql-server

我有3张桌子:

  • Emp (Id(PK),姓名)
  • 地址(AddressId(PK),AddressType)
  • EmpAddress (EmpId(FK),AddresId(FK))

一名员工可能有多个地址。

示例数据:

的Emp

1 abc
2 pqr

地址

1 a
2 b
3 c

EmpAddress

1 1
1 2
1 3

这里empid 1有3个地址。

我希望根据可用性一次只有一个地址。

  • 如果adresstype a可用,则只显示
  • 如果adresstype c可用,则只显示c
  • 如果adresstype b可用,则只显示b

优先级是a-> c-> b

如果只有一个可用,则显示没有任何优先级。

我写了这个查询,但它不起作用:

select * 
from Emp
inner join EmpAddress on Emp.Id = .EmpAddress .Emp
inner join Address on Address.Id = EmpAddress.Address_Id
where AddressType is NOT NULL
  and AddressType = case
                       when AddressType = 'a' then 'a'
                       when AddressType = 'c' then 'c'
                       when AddressType = 'b' then 'b'
                    end

3 个答案:

答案 0 :(得分:1)

一种方法是使用ROW_NUMBER()根据排序a > c > b为每种地址类型分配数字优先级。然后,子查询只保留每个员工的最高排名地址。

SELECT Id, Emp, AddressType
FROM
(
    SELECT e.Id, ea.Emp, a.AddressType,
        ROW_NUMBER() OVER (PARTITION BY e.Id
            ORDER BY CASE WHEN a.AddressType = 'a' THEN 1
                          WHEN a.AddressType = 'b' THEN 2
                          WHEN a.AddressType = 'c' THEN 3 END) rn
    FROM Emp e
    INNER JOIN EmpAddress ea
        ON e.Id = ea.Emp
    INNER JOIN Address a
        ON a.Id = ea.Address_Id
) t
WHERE t.rn = 1;

答案 1 :(得分:0)

 <?php
   $date=date_create("2018-03-15");
   echo date_format($date,"m/d/y H:i:s");
  ?>

答案 2 :(得分:0)

您还可以使用TIES

通过 TOP(1)检索基于优先级的记录
SELECT 
        TOP(1) with TIES e.Id, *
FROM Emp e
INNER JOIN EmpAddress ea ON e.Id = ea.Emp
INNER JOIN Address a ON a.Id = ea.Address_Id
ORDER BY ROW_NUMBER() OVER (PARTITION BY e.Id ORDER BY 
                             CASE (a.AddressType) WHEN 'a' THEN 1
                                    WHEN 'c' THEN 2 WHEN 'b' THEN 3 END)