【问题标题】:Cross tables in a loop循环中的交叉表
【发布时间】:2019-05-06 14:01:18
【问题描述】:

我有这两张桌子

项目移动

Item  Date
A     2018-03-31
A     2018-03-30
A     2018-03-25
B     2018-03-28
B     2018-03-29

和日期表

Date
2018-03-31
2018-03-30
2018-03-29
2018-03-28
2018-03-27
2018-03-26
2018-03-25

我需要的是在这两者之间有一种交叉产品,但仅限于每个项目的最早日期。 最初我使用简单的叉积。

select distinct t.Item, f.Date from ItemMov t cross join DateTable f

得到这个

Item       Date
 A    2018-03-31
 A    2018-03-30
 A    2018-03-29
 A    2018-03-28
 A    2018-03-27
 A    2018-03-26
 A    2018-03-25
 B    2018-03-31
 B    2018-03-30
 B    2018-03-29
 B    2018-03-28
 B    2018-03-27
 B    2018-03-26
 B    2018-03-25

当然,对于某些项目,例如 B,这种交叉会导致日期早于第一次约会。 所需的输出应该是这样的,但仅限于每个项目的 min(date)。那么,是否有为什么要使用交叉表执行此操作,还是应该使用某种循环?

期望的输出

Item       Date
 A    2018-03-31
 A    2018-03-30
 A    2018-03-29
 A    2018-03-28
 A    2018-03-27
 A    2018-03-26
 A    2018-03-25
 B    2018-03-31
 B    2018-03-30
 B    2018-03-29
 B    2018-03-28

【问题讨论】:

  • DISTINCT 不是一个函数,它是SELECT DISTINCT 的一部分,适用于整个选定的行。删除那些额外的括号以使代码更清晰,即只需执行select distinct t.Item, f.Date ...
  • 我不明白您达到预期输出的逻辑。你能解释得更好吗?
  • @TimBiegeleisen 这个想法是每个 Item 都会有日期从 DateTable 中的第一个日期开始的行,但限制了 ItemMov 表中的最早日期。
  • 看你喜不喜欢SELECT i.Item, d.Date FROM DateTable d LEFT JOIN ItemMov i USING(Date)`

标签: mysql sql mariadb


【解决方案1】:

考虑带有on 子句日期表达式的join

select distinct t.Item, f.Date 
from ItemMov t 
inner join DateTable f on t.Date <= f.Date
-- cross join DateTable f on t.Date <= f.Date
order by t.Item, f.Date desc

Rextester demo

【讨论】:

  • 如此简单且有效。内连接不应该只带来两个表中的日期吗? ItemMov 中的 Crearly 物品并非每天都有“动作”。
  • 由于 on 子句不使用完全相等,=inner join 模仿 cross join 但带有子集。其实你可以用cross join代替它!
  • @BenJ。更清楚地说,内连接只返回 ON 子句中的条件评估为 TRUE 的行。如果您只使用= 作为您的条件,那么是的,两个表中的值必须相同。但是你可以使用任何类型的表达式,而不仅仅是=
【解决方案2】:

你可以在做join之前聚合:

select i.item, d.date
from (select i.item, min(date) as min_date, max(date) as max_date
      from itemmov i
      group by i.item
     ) i join
     datetable d
     on d.date >= i.min_date and d.date <= i.max_date
order by i.item, d.date;

【讨论】:

    猜你喜欢
    • 2018-10-01
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多