【问题标题】:Efficient SQL query for selecting records where a related record DOES NOT exist用于选择不存在相关记录的记录的高效 SQL 查询
【发布时间】:2017-06-09 01:19:23
【问题描述】:

我正在尝试选择一个用户,该用户没有具有特定值的关联记录。

我有一个 User 模型,一个 User has_one Feed,一个 Feed has_many FeedTracks,一个 FeedTrack belongs_to Track。我只想选择没有具有特定 TrackId 的 FeedTrack 的用户。

我正在使用 Rails,但我愿意接受严格的 SQL。

我得到的最好的是:

 SELECT TOP 1000 * 
 FROM Users u
 LEFT JOIN Feeds f ON f.user_id = u.id
 LEFT JOIN FeedTracks ft ON ft.feed_id = f.id
 ONLY IF ALL OF THOSE feedTracks' track_id !== <<track_id>>

显然,最后一部分语句不是真正的 SQL,这就是我的问题。我怎么说,嘿,给我这个相关记录不存在的用户。但如果该记录确实存在,则不要返回该用户。

换句话说,如果该用户有一个提要,并且提要跟踪具有该跟踪 ID,则不要返回该用户。但如果没有,请返回该用户。

【问题讨论】:

  • 您似乎定义了错误的架构,如果用户有一个提要,提要表应该有user_id 列,而不是用户表有feed_id 列。请发布您的数据库架构。
  • 很好,谢谢

标签: sql ruby-on-rails sql-server


【解决方案1】:

您可以使用GROUP BYHAVING

SELECT u.id
FROM Users u
LEFT JOIN Feeds f 
    ON f.id = u.feed_id
LEFT JOIN FeedTracks ft 
    ON ft.feed_id = f.id
GROUP BY u.id
HAVING 
    SUM(CASE WHEN ft.track_id = @track_id THEN 1 ELSE 0 END) = 0

根据需要修改SELECTGROUP BY 中的列。

【讨论】:

    【解决方案2】:

    试试

    User.joins(feed: :feed_tracks)
            .where('feed_tracks.track_id <> ?', unwanted_track_id)
            .order('id desc')
            .limit(1000)
            .to_sql
    

    【讨论】:

      【解决方案3】:

      你应该像这样使用not existst操作

       SELECT TOP 1000 * 
       FROM Users u
          LEFT JOIN Feeds f ON f.id = u.feed_id
          LEFT JOIN FeedTracks ft ON ft.feed_id = f.id
       where not exists 
      (select 1 
      from FeedTracks  ft1 
      where ft1.feed_id = f.id 
        and ft1.track_id = <<track_id>>)
      

      【讨论】:

        猜你喜欢
        • 2014-09-10
        • 2018-02-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多