我正在尝试加入两个TBL_CONTACT
和TBL_PHONE
个表。
TBL_PHONE
表包含具有多个电话号码的联系人的重复行,因此我正在对这些行进行分区并尝试仅选择第一个实例。
这是我的代码:
SELECT
(CONTACT.CONTACTID),
(CONTACT.FULLNAME),
(PHONE.contactid),
(PHONE.numberdisplay),
(row_number() OVER(PARTITION BY PHONE.Contactid ORDER BY PHONE.Contactid)) prn
FROM
"ACT2015Demo"."dbo"."TBL_CONTACT" AS CONTACT
INNER JOIN
TBL_PHONE AS PHONE
ON CONTACT.Contactid = PHONE.Contactid
WHERE
CAST(Editdate AS DATE) = CAST(GETDATE() AS DATE)
这给出了以下内容:
CONTACTID FULLNAME CONTACTID NUMBERDISPLAY PRN
1001 Name1 1001 Tel1001 1 1
1001 Name1 1001 Tel1001 2 2
1002 Name2 1002 Tel1002 1 1
1003 Name3 1003 Tel1003 1 1
1003 Name3 1003 Tel1003 2 2
1003 Name3 1003 Tel1003 3 3
然后我想使用PRN列将输出限制为只有PRN = 1的行。我尝试了以下内容,因为这对我来说在过去不太复杂的连接中起作用了:
SELECT
(CONTACT.CONTACTID),
(CONTACT.FULLNAME),
(PHONE.contactid),
(PHONE.numberdisplay),
(row_number() OVER(PARTITION BY PHONE.Contactid ORDER BY PHONE.Contactid)) prn
FROM
"ACT2015Demo"."dbo"."TBL_CONTACT" AS CONTACT
INNER JOIN
TBL_PHONE AS PHONE
ON CONTACT.Contactid = PHONE.Contactid AND PRN = 1
WHERE
CAST(Editdate AS DATE) = CAST(GETDATE() AS DATE)
但是,这会为PRN
提供无效的列名错误?我也尝试将PRN = 1
作为WHERE
的一部分使用,并出现同样的错误。
如何让PRN
作为列名工作并限制输出?
答案 0 :(得分:2)
有些人对SQL有点奇怪和混淆是你在select-list中定义的列别名不能在FROM
子句或WHERE
子句中引用。
这是令人困惑的,因为列别名似乎在查询的早期定义(因为select-list在FROM
子句之前)。但语法的顺序不是执行顺序。
您可以通过将查询作为派生表子查询运行来解决此问题:
SELECT *
FROM (
SELECT
CONTACT.CONTACTID,
CONTACT.FULLNAME,
PHONE.contactid,
PHONE.numberdisplay,
ROW_NUMBER() OVER(PARTITION BY PHONE.Contactid ORDER BY PHONE.Contactid) AS PRN
FROM
"ACT2015Demo"."dbo"."TBL_CONTACT" AS CONTACT
INNER JOIN
TBL_PHONE AS PHONE
ON CONTACT.Contactid = PHONE.Contactid
WHERE
CAST(Editdate AS DATE) = CAST(GETDATE() AS DATE)
) AS DerivedTable
WHERE PRN = 1
PS:MySQL不支持最高5.7版本的窗口函数。已宣布此功能正在开发中,希望它将在MySQL 8中准备好。我想您可能已经错误地标记了您的问题。
您使用架构限定符dbo
这让我觉得您使用的是Microsoft SQL Server或Sybase,这是正确的吗?
答案 1 :(得分:1)
我尝试了以下内容,因为这对我来说在过去不太复杂的连接中起作用了......你尝试过的方法也不会用于简单的连接。你必须使用Derived table或CTE
Select
*
from
(
SELECT
(CONTACT.CONTACTID) as concontactid,
(CONTACT.FULLNAME),
(PHONE.contactid),
(PHONE.numberdisplay),
(row_number() OVER(PARTITION BY PHONE.Contactid ORDER BY PHONE.Contactid)) prn
FROM
"ACT2015Demo"."dbo"."TBL_CONTACT" AS CONTACT
INNER JOIN
TBL_PHONE AS PHONE
ON CONTACT.Contactid = PHONE.Contactid
WHERE
CAST(Editdate AS DATE) = CAST(GETDATE() AS DATE)
) as b
where prn=1
答案 2 :(得分:1)
当 row_number()OVER(PARTITION BY)子句的复合关键字段集出现在连接的两个表中时,也会发生此错误。无论排列或重新排列别名如何,错误都不会消失。要解决此问题,必须在内联临时表中重命名连接表中具有相同名称的键列,如下所示。 更改此内容:
INNER JOIN
TBL_PHONE AS PHONE
ON CONTACT.Contactid = PHONE.Contactid
... some other col_names
etc. ...
到此:
INNER JOIN (
SELECT
Contactid as PK_Contactid,
... some other col_names as PK_col_names,
etc. ...
FROM TBL_PHONE
) AS PHONE
ON CONTACT.Contactid = PHONE.PK_Contactid
... some other col_names
etc. ...
NB。和不要在 row_number()OVER(PARTITION BY)中使用表别名作为任何 col_names 的前缀条款。为我工作。