Simplifying มีการกับครอบการสืบค้น

0

คำถาม

ฉันต้องการจะลบความต้องการสำหรับครอบการสืบค้นถ้าฉันสามารถออกจากการด้านล่างนี้แต่ฉันต้องดิ้นรนเพื่อทำงานออกมาได้ยังไง

นี่คือรูปแบบชุดสี:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE IF NOT EXISTS [dbo].[expiration]
(
    [batch_number] [int] NOT NULL,
    [fruit_number] [int] NOT NULL,
    [store_number] [int] NOT NULL,
    [expiration_date] [date] NULL
) ON [PRIMARY]

CREATE TABLE IF NOT EXISTS [dbo].[fruits]
(
    [fruit_number] [int] NOT NULL,
    [fruit_name] [nvarchar](50) NOT NULL
) ON [PRIMARY]

นี่คือข้อมูล:

INSERT IGNORE INTO [dbo].[expiration] ([batch_number], [fruit_number], [store_number], [expiration_date]) 
VALUES (1, 3, 4, CAST(N'2021-11-25' AS Date))

INSERT IGNORE INTO [dbo].[expiration] ([batch_number], [fruit_number], [store_number], [expiration_date]) 
VALUES (1, 2, 2, CAST(N'2021-11-22' AS Date))

INSERT IGNORE INTO [dbo].[expiration] ([batch_number], [fruit_number], [store_number], [expiration_date]) 
VALUES (1, 5, 3, CAST(N'2021-11-30' AS Date))

INSERT IGNORE INTO [dbo].[expiration] ([batch_number], [fruit_number], [store_number], [expiration_date]) 
VALUES (2, 2, 7, NULL)

INSERT IGNORE INTO [dbo].[expiration] ([batch_number], [fruit_number], [store_number], [expiration_date]) 
VALUES (2, 3, 2, CAST(N'2021-12-12' AS Date))

INSERT IGNORE INTO [dbo].[expiration] ([batch_number], [fruit_number], [store_number], [expiration_date]) 
VALUES (1, 1, 5, NULL)

INSERT IGNORE INTO [dbo].[expiration] ([batch_number], [fruit_number], [store_number], [expiration_date]) 
VALUES (2, 1, 6, CAST(N'2021-11-28' AS Date))

INSERT IGNORE INTO [dbo].[fruits] ([fruit_number], [fruit_name]) 
VALUES (1, N'banana')

INSERT IGNORE INTO [dbo].[fruits] ([fruit_number], [fruit_name]) 
VALUES (2, N'apple')

INSERT IGNORE INTO [dbo].[fruits] ([fruit_number], [fruit_name]) 
VALUES (3, N'pear')

INSERT IGNORE INTO [dbo].[fruits] ([fruit_number], [fruit_name]) 
VALUES (4, N'peach')

INSERT IGNORE INTO [dbo].[fruits] ([fruit_number], [fruit_name]) 
VALUES (5, N'strawberry')

และนี่คือของฉันกับการค้นหา:

SELECT
    fruit_number, 
    MAX(expirationDate) as expirationDate
FROM
    (SELECT
        f.fruit_number,
        CASE
            WHEN e.expiration_date is NULL AND e.fruit_number IS NOT NULL THEN 1
            ELSE 0
        END AS expirationDate
    FROM
        expiration AS e
    FULL OUTER JOIN 
        fruits AS f ON f.fruit_number = e.fruit_number
    WHERE
        f.fruit_number IS NOT NULL) t
GROUP BY
    fruit_number
ORDER BY
    fruit_number

มันยานี้ขึ้นมานี้ถูกตั้งไว้:

fruit_number expirationDate
1 1
2 1
3 0
4 0
5 0

ที่ resultset คือสิ่งที่ฉันหลังจากนั้นแต่มันน่าเกลียดการมีครอบการสืบค้. มันเป็นไปได้ที่ต้องทำทุกอย่างโดยไม่มีครอบการสืบค้? การออนไลน์ query analyser(https://www.eversql.com/sql-query-optimizer/)บอกว่าจะย้ายไปที่รายการย่อยขอบการค้นหาเข้าไปในอุณหภูมิโต๊ะกับการค้นหาต่อต้านอย่างนั้นแต่ไม่ใช่แค่ทำในสิ่งเดียวกันในอีกขั้นตอน?

sql-server tsql
2021-11-23 12:03:11
3

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

2

คนแรกเปลี่ยนฉันจะทำให้เป็นของคุณจะมาร่วมกั. มันไม่มีเหตุผลต้องการใช้ FULL OUTER JOIN งั้นเอาอยู่ที่ไหนข้อตกลงนั้นบอกว่า f.fruit_number IS NOT NULL. นี่หมายความว่าทุกแถวต้องมีบันทึกอยู่ใน fruitsดังนั้นของคุณกับการค้นหาจะฟังดูมีเหตุผลกว่าเหรอที่ SELECT .. FROM fruits AS f LEFT JOIN expiration AS e ON e.fruit_number = f.fruit_number.

คุณยังสามารถลบ subquery โดยยืนยันว่าคดีของคุณแสดงโดยตรงภายใน MAX ฟังก์ชัน:

SELECT  f.fruit_number, 
        f.fruit_name,
        expirationDate = MAX(CASE WHEN e.expiration_date IS NULL 
                                    AND e.fruit_number IS NOT NULL THEN 1 ELSE 0 END)
FROM    dbo.fruits AS f
        LEFT JOIN dbo.expiration AS e
            ON e.fruit_number = f.fruit_number
GROUP BY f.fruit_number, f.fruit_name
ORDER BY f.fruit_number;

ตัวอย่างเช่นบน db<>ลื่นไหล

2021-11-23 12:35:52
0

เอานี่ลอง,ผมเชื่อว่ามันจะได้ในสิ่งที่คุณต้องการ:

SELECT t1.fruit_number
, CASE WHEN MIN(ISNULL(expiration_date, '1/1/1900')) = CAST('1/1/1900' as date) and t2.fruit_number IS NOT NULL THEN 1 ELSE 0 END expirationDate
FROM fruits t1 
LEFT JOIN expiration t2 on t1.fruit_number = t2.fruit_number
GROUP BY t1.fruit_number, t2.fruit_number
ORDER BY t1.fruit_number
2021-11-23 12:24:55
0

มันดูเหมือนว่าคุณเป็น overcomplicating เรื่องนี้ สันนิษฐานว่า fruit_number คือยูนิคอยู่ fruitsนั่นคือไม่จำเป็นต้องเป็น group byแทนที่จะใช้ exists

SELECT
  f.fruit_number, 
  f.fruit_name,
  expirationDate = CASE WHEN EXISTS (SELECT 1
                       FROM dbo.expiration AS e
                       WHERE e.fruit_number = f.fruit_number
                         AND e.expiration_date IS NULL
                     ) THEN 1 ELSE 0 END
FROM dbo.fruits AS f
ORDER BY f.fruit_number;

db<>ลื่นไหล

2021-11-23 16:39:29

ในภาษาอื่นๆ

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

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

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

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