SQL查询以连接两个表并根据ApprovedByLevel获取最新数据。

huangapple go评论76阅读模式
英文:

SQL query to join two tables and get latest data based on ApprovedByLevel

问题

Data Table

创建表格 [dbo].[Data](
[RecordNumber] [int] NULL,
[Data1] nvarchar NULL,
[Data2] nvarchar NULL
) 在 [PRIMARY] 上

Approval Table

创建表格 [dbo].[Approval](
[RecordNumber] [int] NOT NULL,
[ApprovedByLevel] [int] NOT NULL,
[ApprovedByName] nvarchar NOT NULL
) 在 [PRIMARY] 上

在批准表格中,我存储了记录号和批准记录的人。多个人批准同一记录,最后我希望通过合并数据表仅显示最后批准的人的级别和姓名。

Expecting query to Result

使用 Ms-SQL Server 2014

更新

在这个链接中: https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=d1c10b03c62b282d096a1f7d7dbfca4b
我想要获得以下结果:

英文:

Data Table

SQL查询以连接两个表并根据ApprovedByLevel获取最新数据。
.

CREATE TABLE [dbo].[Data](
	[RecordNumber] [int] NULL,
	[Data1] [nvarchar](10) NULL,
	[Data2] [nvarchar](10) NULL
) ON [PRIMARY]

SQL查询以连接两个表并根据ApprovedByLevel获取最新数据。

Approval Table

SQL查询以连接两个表并根据ApprovedByLevel获取最新数据。

CREATE TABLE [dbo].[Approval](
	[RecordNumber] [int] NOT NULL,
	[ApprovedByLevel] [int] NOT NULL,
	[ApprovedByName] [nvarchar](50) NOT NULL
) ON [PRIMARY]

SQL查询以连接两个表并根据ApprovedByLevel获取最新数据。
<br/><br/>In approval table I store the record No. and the person who is approving the record. <br/>Many persons approve the same record and finally I would like to show only the Last Approved By Person Level and Name by combining the data table.<br/><br/>
Expecting query to Result

SQL查询以连接两个表并根据ApprovedByLevel获取最新数据。

Using Ms-SQL Server 2014

> Update

In this

https://dbfiddle.uk/?rdbms=sqlserver_2017&amp;fiddle=d1c10b03c62b282d096a1f7d7dbfca4b

I want to get the result as

SQL查询以连接两个表并根据ApprovedByLevel获取最新数据。

答案1

得分: 3

你可以使用 row_number() 窗口函数来获取结果中所需的 [ApprovedByLevel]

select d.*, 
  COALESCE(a.[ApprovedByLevel], 0) AS [ApprovedByLevel], 
  a.[ApprovedByName]
from [Data] d left join (
  select *, 
    row_number() over (partition by [RecordNumber] order by [ApprovedByLevel] desc) rn
  from [Approval]
) a
on a.[RecordNumber] = d.[RecordNumber] and a.rn = 1

查看 演示

结果:

> RecordNumber | Data1 | Data2 | ApprovedByLevel | ApprovedByName
> -----------: | :---- | :---- | --------------: | :-------------
>         1001 | A     | AA    |               3 | Mr.C          
>         1002 | B     | BB    |               5 | Mr.DD
>         1003 | C     | CC    |               0 | 
英文:

You can use row_number() window function to get the [ApprovedByLevel] that you want in the results:

select d.*, 
  COALESCE(a.[ApprovedByLevel], 0) AS [ApprovedByLevel], 
  a.[ApprovedByName]
from [Data] d left join (
  select *, 
    row_number() over (partition by [RecordNumber] order by [ApprovedByLevel] desc) rn
  from [Approval]
) a
on a.[RecordNumber] = d.[RecordNumber] and a.rn = 1

See the demo.<br/>
Results:

&gt; RecordNumber | Data1 | Data2 | ApprovedByLevel | ApprovedByName
&gt; -----------: | :---- | :---- | --------------: | :-------------
&gt;         1001 | A     | AA    |               3 | Mr.C          
&gt;         1002 | B     | BB    |               5 | Mr.DD
&gt;         1003 | C     | CC    |               0 | 

答案2

得分: 2

I don't know if that helps, but you could use Join with Top 1 in sub select:

你可以尝试在子查询中使用Join与Top 1:

SELECT   *
FROM     dbo.data D
JOIN     dbo.Approval A
ON       A.ApprovedByLevel =
         (
         SELECT  TOP 1 ApprovedByLevel 
         FROM    Approval 
         WHERE   RecordNumber = D.RecordNumber
         order by ApprovedByLevel desc
         )

Note: You will have problems when there are more records with the same
value in approvedlevel. You need a unique ID for the tabel
dbo.approval. This should then be used in join condition.

注意:如果approvedlevel中有多条记录具有相同的值,你可能会遇到问题。你需要为dbo.approval表添加一个唯一的ID。然后,这个唯一ID应该用于连接条件。

If you have a RecordNumber in dbo.data but not in dbo.Approval, you could use left outer join:

如果在dbo.data中有一个RecordNumber,但在dbo.Approval中没有,你可以使用left outer join

SELECT   *
FROM     dbo.data D
LEFT OUTER JOIN dbo.Approval A
ON       A.ApprovedByLevel =
         (
         SELECT  TOP 1 ApprovedByLevel 
         FROM    Approval 
         WHERE   RecordNumber = D.RecordNumber
         order by ApprovedByLevel desc
         )

If you need Zero values instead of NULL you could use ISNULL()-Function:

如果你需要零值而不是NULL,你可以使用ISNULL()-Function

SELECT   D.*, ISNULL(A.ApprovedByLevel,0), A.ApprovedByName
FROM     dbo.data D
LEFT OUTER JOIN dbo.Approval A
ON       A.ApprovedByLevel =
         (
         SELECT  TOP 1 ApprovedByLevel 
         FROM    Approval 
         WHERE   RecordNumber = D.RecordNumber
         order by ApprovedByLevel desc
         )
英文:

I dont know if that helps, but you could use Join with Top 1 in sub select:

SELECT   *
FROM     dbo.data D
JOIN     dbo.Approval A
ON       A.ApprovedByLevel =
         (
         SELECT  TOP 1 ApprovedByLevel 
         FROM    Approval 
         WHERE   RecordNumber = D.RecordNumber
		 order by ApprovedByLevel desc
         )

> Note: You will have problems when there are more records with the same
> value in approvedlevel. You need a unique ID for the tabel
> dbo.approval. This should then be used in join condition.

If you have a RecordNumber in dbo.data but not in dbo.Approval, you could use left outer join:

SELECT   *
FROM     dbo.data D
LEFT OUTER JOIN dbo.Approval A
ON       A.ApprovedByLevel =
         (
         SELECT  TOP 1 ApprovedByLevel 
         FROM    Approval 
         WHERE   RecordNumber = D.RecordNumber
         order by ApprovedByLevel desc
         )

If you need Zero values instead of NULL you could use ISNULL()-Function:

SELECT   D.*, ISNULL(A.ApprovedByLevel,0), A.ApprovedByName
FROM     dbo.data D
LEFT OUTER JOIN dbo.Approval A
ON       A.ApprovedByLevel =
         (
         SELECT  TOP 1 ApprovedByLevel 
         FROM    Approval 
         WHERE   RecordNumber = D.RecordNumber
         order by ApprovedByLevel desc
         )

答案3

得分: 1

我建议您添加一个名为 ApprovingDate 的日期列,以避免在具有相同的 ApprovedLevel 值的更多记录时出现问题:

SQL Fiddle

MS SQL Server 2017 Schema Setup:

CREATE TABLE [dbo].[Data](
    [RecordNumber] [int] NULL,
    [Data1] [nvarchar](10) NULL,
    [Data2] [nvarchar](10) NULL
)
INSERT INTO dbo.[Data]([RecordNumber],[Data1],[Data2])
VALUES(1001,'A','AA'),(1002,'B','BB')

CREATE TABLE [dbo].[Approval](
    [RecordNumber] [int] NOT NULL,
    [ApprovedByLevel] [int] NOT NULL,
    [ApprovedByName] [nvarchar](50) NOT NULL
) 
INSERT INTO [dbo].[Approval] VALUES(1001,1,'Mr.A'),(1001,2,'Mr.B'),
                            (1002,2,'Mr.AA'),(1001,3,'Mr.C'),
                            (1002,5,'Mr.DD')

Query 1:

select TOP 2 * from Approval as da 
inner join [data] as dd on da.recordnumber = dd.recordnumber 
order by da.approvedbylevel DESC

Query 2:

SELECT   *
FROM     dbo.data dt
JOIN     dbo.Approval a
ON       a.ApprovedByLevel =
         (
         SELECT  TOP 1 ApprovedByLevel 
         FROM    Approval 
         WHERE   RecordNumber = dt.RecordNumber
         order by ApprovedByLevel desc
         )

Results:

| RecordNumber | Data1 | Data2 | RecordNumber | ApprovedByLevel | ApprovedByName |
|--------------|-------|-------|--------------|-----------------|----------------|
|         1001 |     A |    AA |         1001 |               3 |           Mr.C |
|         1002 |     B |    BB |         1002 |               5 |          Mr.DD |
英文:

I would suggest you to add a date column ApprovingDate to avoid having problems when there are more records with the same value in ApprovedLevel :

SQL Fiddle

MS SQL Server 2017 Schema Setup:

CREATE TABLE [dbo].[Data](
    [RecordNumber] [int] NULL,
    [Data1] [nvarchar](10) NULL,
    [Data2] [nvarchar](10) NULL
)
INSERT INTO dbo.[Data]([RecordNumber],[Data1],[Data2])
VALUES(1001,&#39;A&#39;,&#39;AA&#39;),(1002,&#39;B&#39;,&#39;BB&#39;)
CREATE TABLE [dbo].[Approval](
    [RecordNumber] [int] NOT NULL,
    [ApprovedByLevel] [int] NOT NULL,
    [ApprovedByName] [nvarchar](50) NOT NULL
) 
INSERT INTO [dbo].[Approval] VALUES(1001,1,&#39;Mr.A&#39;),(1001,2,&#39;Mr.B&#39;),
                            (1002,2,&#39;Mr.AA&#39;),(1001,3,&#39;Mr.C&#39;),
                            (1002,5,&#39;Mr.DD&#39;)

Query 1:

select TOP 2 * from Approval as da 
inner join [data] as dd on da.recordnumber = dd.recordnumber 
order by da.approvedbylevel DESC

Query 2:

SELECT   *
FROM     dbo.data dt
JOIN     dbo.Approval a
ON       a.ApprovedByLevel =
         (
         SELECT  TOP 1 ApprovedByLevel 
         FROM    Approval 
         WHERE   RecordNumber = dt.RecordNumber
         order by ApprovedByLevel desc
         )

Results:

| RecordNumber | Data1 | Data2 | RecordNumber | ApprovedByLevel | ApprovedByName |
|--------------|-------|-------|--------------|-----------------|----------------|
|         1001 |     A |    AA |         1001 |               3 |           Mr.C |
|         1002 |     B |    BB |         1002 |               5 |          Mr.DD |

huangapple
  • 本文由 发表于 2020年1月3日 17:23:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/59575931.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定