簡體   English   中英

Rails和查詢-自定義查詢以獲取重復的記錄

[英]Rails and queries - Custom query to get duplicated records

在大多數情況下,我盡量不使用我的應用程序編寫自定義SQL查詢,但我錯了一個案子,我想知道這是否是我最好做的情況。

我在這個特定的應用程序中使用PostgreSQL。 我只想返回被雙重預定任務的員工,這是我的模型。

我有以下型號的波紋管。

用戶

has_many :user_jobs

    Fields
    - id
    - name
    - address
    - phone

工作

has_many :user_jobs
has_many :users, through: :user_jobs

    Fields
    - id
    - date
    - start_time
    - end_time

UserJobs

belongs_to :user
belongs_to :jobs

    Fields
    - id
    - job_id
    - user_id

Userjobs是保存工作和該工作的雇員的表,但是每個工作的日期和時間都保存在Job表中

我想返回類似

user(employee) - date and time job1 - date and time job1

編輯:添加了更多架構詳細信息

CREATE TABLE user_jobs (
    id integer NOT NULL,
    job_id integer,
    job_date date,
    notes text,
    job_rating integer,
    notes text,
    created_at timestamp without time zone,
    updated_at timestamp without time zone,
    user_id integer,
);


CREATE TABLE jobs (
    id integer NOT NULL,
    date date,
    start_time time without time zone,
    end_time time without time zone,
    notes text,
);


CREATE TABLE users (
    id integer NOT NULL,
    email character varying(255) DEFAULT ''::character varying NOT NULL,
    name character varying(255),
    address character varying(255),
    phone character varying(255),
    picture character varying(255),
    status character varying(255) DEFAULT 'active'::character varying,
);

提前致謝

Postgres 9.2以上

這有點陳舊:

WITH alljobs AS(
  SELECT * FROM jobs j INNER JOIN user_jobs uj ON uj.job_id = j.id
) 
SELECT DISTINCT q1.user_id
FROM alljobs q1
JOIN alljobs q2 on
      q1.user_id = q2.user_id
  AND tsrange(q1.date + q1.start_time, q1.date + q1.end_time) && tsrange(q2.date + q2.start_time, q2.date + q2.end_time)

說明:

  • WITH alljobs有效地將變量名稱alljobs分配給給定查詢。 該查詢只是所有作業分配的合並列表,包括開始時間和結束時間。
  • SELECT DISTINCT q1.user_id僅返回被重復預訂的用戶的ID。 從技術上講,這是您所要的,盡管您可能希望擴展此選擇以獲取更多有用的信息。 我建議在調試時使用SELECT *
  • FROM alljobs q1 JOIN alljobs q2這將作業與自身進行聯接,這是將每個作業與其他作業進行比較所必需的。
  • q1.user_id = q2.user_id我們只關心單個用戶的沖突。 如果您想回答諸如“誰在一起工作?”之類的相關問題,則可以更改此設置。
  • tsrange一個postgres內置范圍函數 ,該函數從兩個時間戳創建一個范圍。 日期和其他類型的時間戳具有類似的功能。 _這些范圍類型僅在9.2中引入。
  • &&一個postgres范圍運算符,用於交集。

Postgres <9.2

您可以使用自己的交集邏輯替換tsrange&& ,我認為它類似於: q1.start_time < q2.start_time && q1.finish_time > q2.start_time OR q2.start_time < q1.start_time && q2.finish_time > q1.start_time (以及添加date 。)

或者,由於您指定的開始時間始終是相同的,而且實際上這就是您關心的全部,因此在這種情況下,您可以做一些簡單的事情:

SELECT user_id, date + start_time, COUNT(*)
FROM user_jobs INNER JOIN jobs ON job_id = jobs.id
GROUP BY user_id, date + start_time
HAVING COUNT(*) > 2

這將為您提供所有重復的用戶ID。 要獲取相應的作業,可以將其包裝在外部查詢中。

SELECT user_jobs.user_id, user_jobs.job_id, jobs.date + jobs.start_time
FROM user_jobs INNER JOIN jobs ON job_id = jobs.id INNER JOIN (
  SELECT user_id, date + start_time, COUNT(*)
  FROM user_jobs INNER JOIN jobs ON job_id = jobs.id
  GROUP BY user_id, date + start_time
  HAVING COUNT(*) > 2
) dups ON dups.user_id = user_jobs.user_id
      AND dups.date + dups.start_time = job.date + jobs.start_time

模式建議

通過使用單獨的datetime列,您將使自己的生活更加困難。 為什么不僅僅設置start_timeend_time時間戳? 然后,您不必總是將它們加在一起,並且仍然可以通過強制轉換獲得日期。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM