TSQL:เลือกตัวเลือกพ่อแม่วางเงื่อนไขขึ้นเด็กคน

0

คำถาม

ผมมีผู้ปกครองโต๊ะ Orders และยังเด็กโต๊ะ Jobs กับคนติดตามตัวอย่างข้อมูล enter image description here

ฉันต้องการเพื่อเลือกคำสั่งดูจากตามความต้องการ

1>สำหรับแต่ละคำสั่งนั่นอาจจะเป็น 0 หรือมากกว่างาน ทำไม่ได้เลือกคำสั่งให้หากมันยังไม่มีงานทำ
2>เป็นของผู้ใช้ไม่สามารถทำงานมากกว่าหนึ่งงานที่เป็นของคนเดียวกันคำสั่ง
สำหรับตัวอย่างของผู้ใช้ 1 ไม่สามารถทำงานอยู่ที่งานนั้นเป็นของลำดับ 1 และ 2 เพราะว่าเขาอยู่แล้วทำงาน 1 แล้ว 4 มาจากที่เดียวกันคำสั่ง
3>เดียวที่เลือกคำสั่งว่าต้องทำงานอยู่ Requested สถานะ

ฉันต้องตามสืบค้นที่ทำให้ฉันคาดหวังผลลัพธ์

DECLARE @UserID INT = 2

SELECT O.OrderID
FROM Orders O
JOIN Jobs J ON J.OrderID = O.OrderID
WHERE 
J.JobStatus = 'Requested' AND
NOT EXISTS
(  
    --Must not have worked this Order
    SELECT 1 FROM Jobs J1
    WHERE J1.OrderID = O.OrderID AND J1.UserID = @UserID
)
Group By o.OrderID

ภาษา sql น Fiddle สาธิต

กับการค้นหาจะมาร่วมกันที่ Jobs โต๊ะสองครั้ง ฉันกำลังพยายาม the result will be artificially smoothed to hide jpeg artefacts กับการค้นหาและตามหาหนทางที่จะประสบความสำเร็จให้ได้ผลลัพธ์ตามที่คาดหวังโดยการใช้ Jobs โต๊ะเพียงครั้งเดียวถ้าเป็นไปได้ มีอีกทางออกเป็นเกียรติอย่างยิ่ง ฉันสามารถเปลี่ยนแปลงโต๊ะรูปแบบชุดสีถ้าต้องการ.

งานโต๊ะเกือบจะ 20M นวนแถวและบางครั้งการแสดงที่น่าสงสารการแสดง. (ใช่พวกเรามองไปที่ indexes). ฉันคิดว่ามันกำลังค้นงานนั่งโต๊ะสองครั้งเนื่องจากการแสดงเหมือนไม่มีปัญหาอยู่เลยสินะ

2

คำตอบที่ดีที่สุด

1

ถ้าเล็งเป็นเพียงแค่ต้อง"ใช้งานโต๊ะเพียงครั้งเดียว"ฉันจะพยายามอย่าง:

DECLARE @UserID INT = 2
    
SELECT 
    O.OrderID
FROM 
    Orders O
    INNER JOIN Jobs J ON J.OrderID = O.OrderID  
GROUP BY
    O.OrderID
HAVING
    SUM(CASE WHEN J.JobStatus = 'Requested' THEN 1 ELSE 0 END) > 0
    AND SUM(CASE WHEN J.UserID = @UserId THEN 1 ELSE 0 END) = 0

ภาษา sql ลื่นไหล

ต้อง the result will be artificially smoothed to hide jpeg artefacts ไกลกว่านี้ฉันจะแนะนำว่าหาคนมาแทนที่ varchar datatype ของ JobStatus คอลัมน์กับ tinyint หนึ่ง(และสร้าง JobStatuses โต๊ะ). ครั้งนึงของคุณ Job โต๊ะมี 20M บันทึกนั้น varchar(10) ทำให้คุณ 190 Mb อย่างไรก็ตามโดยใช้ tinyint reduces คอลัมน์ของขนาดต้อ 19 เมกะไบต์—นี่จะทำให้เธอน้อยลงบ io-อ่านปฏิบัติการ

และฉันจะพยายามที่จะแยกออกเด็กกำลังกรองจะร่วมมือกับมันกับพ่อแม่เด็กซะ ช่างเข้าใกล้อาจจะใช้เวลาน้อยความทรงจำสำหรับนัดเดียวปฏิบัติการแล้วชนะในการแสดงเพราะเรื่องนั้น:

DECLARE @UserID INT = 2
DECLARE @OrderIDs TABLE (OrderID INT NOT NULL PRIMARY KEY)

INSERT IGNORE INTO @OrderIDs
SELECT
    OrderID
FROM
    Jobs
GROUP BY
    OrderID
HAVING
    SUM(CASE WHEN JobStatus = 'Requested' THEN 1 ELSE 0 END) > 0
    AND SUM(CASE WHEN UserID = @UserId THEN 1 ELSE 0 END) = 0

SELECT
    O.*
FROM
    Orders O
    INNER JOIN @OrderIDs ids on ids.OrderID = O.OrderID
2021-11-16 09:14:13

งานสถานะเป็นจริง ID ประเภทน int ได้. แค่สำหรับความเข้าใจตั้งใจฉันเก็บมันเป็น nvarchar
LP13

กับเรื่องนี้เข้าใกล้ดูเหมือนฉันไม่ต้องเข้าร่วมกับคำสั่งโต๊ะด้วย ฉันสามารถตรงใช้งานโต๊ะเพื่อได้ OrderID
LP13
0

คุณอาจจะพิจารณาการเพิ่มความดัชนีไป Jobs โต๊ะ:

CREATE INDEX idx_jobs ON Jobs (OrderID, UserID, JobStatus);

นี่ดัชนีถ้าใช้มันควรจะเพิ่มความเร็วที่ไม่มีอยู่จริ subquery อยู่ของคุณค้นเบื้องบน แล้วก็มันสามารถถูกใช้สำหรับผู้เข้าร่วมจาก Orders ต้อง Jobs ในคริงๆข้างนระดับบนสุดกับการค้นหา(ถึงแม้ว่าภาษา sql เซิร์ฟเวอร์อาจจะต้องทำดัชนีตรวจค้น).

2021-11-16 08:40:46

ในภาษาอื่นๆ

หน้านี้อยู่ในภาษาอื่นๆ

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

ดังอยู่ในนี้หมวดหมู่

ดังคำถามอยู่ในนี้หมวดหมู่