SQL 服务器 SELECT 第一次出现或如果没有出现 SELECT 其他条件
SQL Server SELECT first occurrence OR if no occurrence SELECT other criteria
我在尝试为此处的工作形成正确的 SQL 查询时遇到问题。我有两个 table,一个叫 CUSTOMER,另一个叫 CUSTOMER_CONTACT。为了简化这一点,我将只包括相关的列名。
CUSTOMER
列:ID、CUSTOMERNAME
CUSTOMER_CONTACT
列:ID,CUSTOMER_ID,CONTACT_VC,EMAIL
CUSTOMER_ID
是 link 从 CUSTOMER_CONTACT
到 CUSTOMER
table 的外键。 CONTACT_VC
只是他们联系信息的条目号。每个客户可能有多个 CUSTOMER_CONTACT
记录,但他们将有一个唯一的 CONTACT_VC
。
EMAIL
也可以是部分或全部 null/blank。
我需要 select 第一个 CUSTOMER_CONTACT
条目,其中 EMAIL
是 NOT NULL
/空白但是如果 none 的 CUSTOMER_CONTACT
条目有一个电子邮件地址,然后 select CUSTOMER_CONTACT WHERE CONTACT_VC = 1
关于如何完成此操作有什么建议吗?
以下方法使用 ROW_NUMBER 根据您在每个 CUSTOMER_ID
组中的排序逻辑检索数字,然后按检索到的第一条记录进行过滤。
您可以尝试以下方法:
SELECT
*
FROM (
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY CUSTOMER_ID
ORDER BY (CASE WHEN EMAIL IS NOT NULL THEN 0 ELSE 1 END),CONTACT_VC
) as rn
FROM
CUSTOMER_CONTACT
) t
WHERE rn=1
如果您想将此连接到客户table,您可以将上述查询用作子查询,例如
SELECT
c.*,
contact.*
FROM
CUSTOMER c
INNER JOIN (
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY CUSTOMER_ID
ORDER BY (CASE WHEN EMAIL IS NOT NULL THEN 0 ELSE 1 END),CONTACT_VC
) as rn
FROM
CUSTOMER_CONTACT
) contact ON c.ID = contact.CUSTOMER_ID and contact.rn=1
这是与 ggordon 几乎相同的答案,但我使用了一个常见的 table 表达式,我认为子查询部分中的顺序应该先按 CONTACT_VS 然后按非 NULL 电子邮件地址.我为 运行 创建了一些非常简单的测试数据:
DECLARE @CUSTOMER AS TABLE
(
[ID] INT NOT NULL,
[CUSTOMERNAME] VARCHAR(10) NOT NULL
);
INSERT INTO @CUSTOMER
(
[ID],
[CUSTOMERNAME]
)
VALUES
(1, 'Alice'),
(2, 'Bob'),
(3, 'Cathy');
DECLARE @CUSTOMER_CONTACT AS TABLE
(
[ID] INT NOT NULL,
[CUSTOMER_ID] INT NOT NULL,
[CONTACT_VC] INT NOT NULL,
[EMAIL] VARCHAR(40) NULL
);
INSERT INTO @CUSTOMER_CONTACT
(
[ID],
[CUSTOMER_ID],
[CONTACT_VC],
[EMAIL]
)
VALUES
(1, 1, 1, 'alice@email.com'),
(2, 1, 2, 'alice@gmail.com'),
(3, 2, 1, NULL),
(4, 2, 2, 'bob@work.com'),
(5, 3, 1, NULL),
(6, 3, 2, NULL),
(7, 3, 3, NULL);
;WITH [cc]
AS (SELECT [ID],
[CUSTOMER_ID],
[CONTACT_VC],
[EMAIL],
ROW_NUMBER() OVER (PARTITION BY [CUSTOMER_ID]
ORDER BY [CONTACT_VC],
(CASE WHEN [EMAIL] IS NOT NULL THEN
0
ELSE
1
END
)
) AS [rn]
FROM @CUSTOMER_CONTACT)
SELECT [c].[ID], [c].[CUSTOMERNAME], [cc].[ID], [cc].[CUSTOMER_ID], [cc].[CONTACT_VC], [cc].[EMAIL]
FROM @CUSTOMER AS [c]
INNER JOIN [cc]
ON [c].[ID] = [cc].[CUSTOMER_ID]
AND [cc].[rn] = 1;
select * from CUSTOMER_CONTACT where EMAIL IS NOT NULL
union all
select * from CUSTOMER_CONTACT where
(CONTACT_VC=1 and NOT EXISTS (select 1 FROM CUSTOMER_CONTACT where EMAIL IS NOT NUL)
order by CONTACT_VC asc limit 1
我在尝试为此处的工作形成正确的 SQL 查询时遇到问题。我有两个 table,一个叫 CUSTOMER,另一个叫 CUSTOMER_CONTACT。为了简化这一点,我将只包括相关的列名。
CUSTOMER
列:ID、CUSTOMERNAMECUSTOMER_CONTACT
列:ID,CUSTOMER_ID,CONTACT_VC,EMAIL
CUSTOMER_ID
是 link 从 CUSTOMER_CONTACT
到 CUSTOMER
table 的外键。 CONTACT_VC
只是他们联系信息的条目号。每个客户可能有多个 CUSTOMER_CONTACT
记录,但他们将有一个唯一的 CONTACT_VC
。
EMAIL
也可以是部分或全部 null/blank。
我需要 select 第一个 CUSTOMER_CONTACT
条目,其中 EMAIL
是 NOT NULL
/空白但是如果 none 的 CUSTOMER_CONTACT
条目有一个电子邮件地址,然后 select CUSTOMER_CONTACT WHERE CONTACT_VC = 1
关于如何完成此操作有什么建议吗?
以下方法使用 ROW_NUMBER 根据您在每个 CUSTOMER_ID
组中的排序逻辑检索数字,然后按检索到的第一条记录进行过滤。
您可以尝试以下方法:
SELECT
*
FROM (
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY CUSTOMER_ID
ORDER BY (CASE WHEN EMAIL IS NOT NULL THEN 0 ELSE 1 END),CONTACT_VC
) as rn
FROM
CUSTOMER_CONTACT
) t
WHERE rn=1
如果您想将此连接到客户table,您可以将上述查询用作子查询,例如
SELECT
c.*,
contact.*
FROM
CUSTOMER c
INNER JOIN (
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY CUSTOMER_ID
ORDER BY (CASE WHEN EMAIL IS NOT NULL THEN 0 ELSE 1 END),CONTACT_VC
) as rn
FROM
CUSTOMER_CONTACT
) contact ON c.ID = contact.CUSTOMER_ID and contact.rn=1
这是与 ggordon 几乎相同的答案,但我使用了一个常见的 table 表达式,我认为子查询部分中的顺序应该先按 CONTACT_VS 然后按非 NULL 电子邮件地址.我为 运行 创建了一些非常简单的测试数据:
DECLARE @CUSTOMER AS TABLE
(
[ID] INT NOT NULL,
[CUSTOMERNAME] VARCHAR(10) NOT NULL
);
INSERT INTO @CUSTOMER
(
[ID],
[CUSTOMERNAME]
)
VALUES
(1, 'Alice'),
(2, 'Bob'),
(3, 'Cathy');
DECLARE @CUSTOMER_CONTACT AS TABLE
(
[ID] INT NOT NULL,
[CUSTOMER_ID] INT NOT NULL,
[CONTACT_VC] INT NOT NULL,
[EMAIL] VARCHAR(40) NULL
);
INSERT INTO @CUSTOMER_CONTACT
(
[ID],
[CUSTOMER_ID],
[CONTACT_VC],
[EMAIL]
)
VALUES
(1, 1, 1, 'alice@email.com'),
(2, 1, 2, 'alice@gmail.com'),
(3, 2, 1, NULL),
(4, 2, 2, 'bob@work.com'),
(5, 3, 1, NULL),
(6, 3, 2, NULL),
(7, 3, 3, NULL);
;WITH [cc]
AS (SELECT [ID],
[CUSTOMER_ID],
[CONTACT_VC],
[EMAIL],
ROW_NUMBER() OVER (PARTITION BY [CUSTOMER_ID]
ORDER BY [CONTACT_VC],
(CASE WHEN [EMAIL] IS NOT NULL THEN
0
ELSE
1
END
)
) AS [rn]
FROM @CUSTOMER_CONTACT)
SELECT [c].[ID], [c].[CUSTOMERNAME], [cc].[ID], [cc].[CUSTOMER_ID], [cc].[CONTACT_VC], [cc].[EMAIL]
FROM @CUSTOMER AS [c]
INNER JOIN [cc]
ON [c].[ID] = [cc].[CUSTOMER_ID]
AND [cc].[rn] = 1;
select * from CUSTOMER_CONTACT where EMAIL IS NOT NULL
union all
select * from CUSTOMER_CONTACT where
(CONTACT_VC=1 and NOT EXISTS (select 1 FROM CUSTOMER_CONTACT where EMAIL IS NOT NUL)
order by CONTACT_VC asc limit 1