加入多个表返回重复项
Joining multiple tables returning duplicates
我正在尝试以下 select 语句,其中包括来自 4 个表的列。但是结果 return 每行 4 次,我确定这是因为我有多个左连接但我尝试了其他连接但无法获得所需的结果。
select table1.empid,table2.name,table2.datefrom, table2.UserDefNumber1, table3.UserDefNumber1, table4.UserDefChar6
from table1
inner join table2
on table2.empid=table1.empid
inner join table3
on table3.empid=table1.empid
inner join table4
on table4.empid=table1.empid
where MONTH(table2.datefrom) = Month (Getdate())
我需要这个 return 没有任何重复的数据,所以每个条目只有 1 行。
我还希望最后的 "where Month" 子句查看上个月而不是当前月份,但也在努力解决这个问题。
我对此有点陌生,所以我希望它有意义。
谢谢
如果重复行在每一列上都相同,您可以使用 DISTINCT
关键字来消除这些重复项。
但我认为您应该重新考虑您的 JOIN
或 WHERE
子句,因为这些重复项必须有原因:
- WHERE 子句在同一个 empid 上命中 table2 中具有相同月份的几行
- 其他表中有几行具有相同的 empid
- 以上都是正确的
您可能希望通过 WHERE/JOIN 中的条件而不是 DISTINCT
关键字来排除那些重复的行,因为当某些数据在原始结果集的单行中发生变化时可能会出现意外行为.然后你又开始有重复的empids。
您可以通过以下子句检查日期是否在上个月:
date BETWEEN dateadd(mm, -1, datefromparts(year(getdate()), month(getdate()), 1))
AND datefromparts(year(getdate()), month(getdate()), 1)
这个语句使用DATEFROMPARTS
两次创建当月的开始,使用DATEADD
从第一个减去一个月(结果是上个月的开始)并检查是否date
在使用 BETWEEN
的那些日期之间。
通过在 select
之后立即包含 distinct
关键字来消除查询中的重复项
与上个月相比稍微复杂一些。这取决于你的意思:
如果报告是 运行 于 2015 年 1 月 23 日,您想要 01/12/2014-31/12/2014 还是 23/12/2014-22/01/2015?
如果您的查询返回重复项,则说明一个或多个表具有重复的 empid
值。这是一个 data 问题。您可以通过这样的查询找到它们:
select empid, count(*)
from table1
group by empid
having count(*) > 1;
您真的应该修复数据并进行查询,以便 returns 您想要什么。你可以用 select distinct
做绷带解决方案,但我通常不建议这样做。某些原因导致了重复,如果您不明白原因,则查询可能不会返回您期望的结果。
至于你的where
条款。根据您的逻辑,正确的表达方式应该包括年份:
where year(table2.datefrom) = year(getdate()) and
month(table2.datefrom) = month(Getdate())
虽然还有其他方式可以表达与索引更兼容的逻辑,但您可以继续学习本课程:
where year(table2.datefrom) * 12 + month(table2.datefrom) = year(getdate()) * 12 + Month(Getdate()) - 1
即将月份转换为自零时起的月份数,然后使用月份运算。
如果您关心索引,那么您当前的 where
子句将如下所示:
where table2.datefrom >= dateadd(day,
- (day(getdate) - 1),
cast(getdate() as date) and
table2.datefrom < dateadd(day,
- (dateadd(month, 1, getdate()) - 1),
cast(dateadd(month, 1, getdate()) as date)
我正在尝试以下 select 语句,其中包括来自 4 个表的列。但是结果 return 每行 4 次,我确定这是因为我有多个左连接但我尝试了其他连接但无法获得所需的结果。
select table1.empid,table2.name,table2.datefrom, table2.UserDefNumber1, table3.UserDefNumber1, table4.UserDefChar6
from table1
inner join table2
on table2.empid=table1.empid
inner join table3
on table3.empid=table1.empid
inner join table4
on table4.empid=table1.empid
where MONTH(table2.datefrom) = Month (Getdate())
我需要这个 return 没有任何重复的数据,所以每个条目只有 1 行。
我还希望最后的 "where Month" 子句查看上个月而不是当前月份,但也在努力解决这个问题。
我对此有点陌生,所以我希望它有意义。
谢谢
如果重复行在每一列上都相同,您可以使用 DISTINCT
关键字来消除这些重复项。
但我认为您应该重新考虑您的 JOIN
或 WHERE
子句,因为这些重复项必须有原因:
- WHERE 子句在同一个 empid 上命中 table2 中具有相同月份的几行
- 其他表中有几行具有相同的 empid
- 以上都是正确的
您可能希望通过 WHERE/JOIN 中的条件而不是 DISTINCT
关键字来排除那些重复的行,因为当某些数据在原始结果集的单行中发生变化时可能会出现意外行为.然后你又开始有重复的empids。
您可以通过以下子句检查日期是否在上个月:
date BETWEEN dateadd(mm, -1, datefromparts(year(getdate()), month(getdate()), 1))
AND datefromparts(year(getdate()), month(getdate()), 1)
这个语句使用DATEFROMPARTS
两次创建当月的开始,使用DATEADD
从第一个减去一个月(结果是上个月的开始)并检查是否date
在使用 BETWEEN
的那些日期之间。
通过在 select
distinct
关键字来消除查询中的重复项
与上个月相比稍微复杂一些。这取决于你的意思:
如果报告是 运行 于 2015 年 1 月 23 日,您想要 01/12/2014-31/12/2014 还是 23/12/2014-22/01/2015?
如果您的查询返回重复项,则说明一个或多个表具有重复的 empid
值。这是一个 data 问题。您可以通过这样的查询找到它们:
select empid, count(*)
from table1
group by empid
having count(*) > 1;
您真的应该修复数据并进行查询,以便 returns 您想要什么。你可以用 select distinct
做绷带解决方案,但我通常不建议这样做。某些原因导致了重复,如果您不明白原因,则查询可能不会返回您期望的结果。
至于你的where
条款。根据您的逻辑,正确的表达方式应该包括年份:
where year(table2.datefrom) = year(getdate()) and
month(table2.datefrom) = month(Getdate())
虽然还有其他方式可以表达与索引更兼容的逻辑,但您可以继续学习本课程:
where year(table2.datefrom) * 12 + month(table2.datefrom) = year(getdate()) * 12 + Month(Getdate()) - 1
即将月份转换为自零时起的月份数,然后使用月份运算。
如果您关心索引,那么您当前的 where
子句将如下所示:
where table2.datefrom >= dateadd(day,
- (day(getdate) - 1),
cast(getdate() as date) and
table2.datefrom < dateadd(day,
- (dateadd(month, 1, getdate()) - 1),
cast(dateadd(month, 1, getdate()) as date)