英文:
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
CREATE TABLE [dbo].[Data](
[RecordNumber] [int] NULL,
[Data1] [nvarchar](10) NULL,
[Data2] [nvarchar](10) NULL
) ON [PRIMARY]
Approval Table
CREATE TABLE [dbo].[Approval](
[RecordNumber] [int] NOT NULL,
[ApprovedByLevel] [int] NOT NULL,
[ApprovedByName] [nvarchar](50) NOT NULL
) ON [PRIMARY]
<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
Using Ms-SQL Server 2014
> Update
In this
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=d1c10b03c62b282d096a1f7d7dbfca4b
I want to get the result as
答案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:
> RecordNumber | Data1 | Data2 | ApprovedByLevel | ApprovedByName
> -----------: | :---- | :---- | --------------: | :-------------
> 1001 | A | AA | 3 | Mr.C
> 1002 | B | BB | 5 | Mr.DD
> 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 值的更多记录时出现问题:
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
)
| 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 :
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
)
| RecordNumber | Data1 | Data2 | RecordNumber | ApprovedByLevel | ApprovedByName |
|--------------|-------|-------|--------------|-----------------|----------------|
| 1001 | A | AA | 1001 | 3 | Mr.C |
| 1002 | B | BB | 1002 | 5 | Mr.DD |
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论