Trả về một giá trị nếu không tìm thấy hàng nào trong Microsoft tSQL


94

Sử dụng phiên bản SQL của Microsoft , đây là truy vấn đơn giản của tôi. Nếu tôi truy vấn một bản ghi không tồn tại thì tôi sẽ không nhận được gì trả về. Tôi muốn rằng false (0) được trả về trong trường hợp đó. Tìm kiếm phương pháp đơn giản nhất để giải trình không có hồ sơ.

SELECT  CASE
            WHEN S.Id IS NOT NULL AND S.Status = 1 AND (S.WebUserId = @WebUserId OR S.AllowUploads = 1) THEN 1
            ELSE 0
        END AS [Value]

        FROM Sites S

        WHERE S.Id = @SiteId

Câu trả lời:


64
SELECT CASE WHEN COUNT(1) > 0 THEN 1 ELSE 0 END AS [Value]

FROM Sites S

WHERE S.Id = @SiteId and S.Status = 1 AND 
      (S.WebUserId = @WebUserId OR S.AllowUploads = 1)

Truy vấn dưới đây trả về một giá trị duy nhất trong điều kiện khác, nhưng lý tưởng là nó phải trả về nhiều giá trị. chọn trường hợp khi số lượng (QTIB_REQ _) <1 rồi đến 0 khác QTIB_REQ_ kết thúc từ qb_requisitions_all trong đó QTIB_REQ_ IN ($ Req_disabled_WA) và CLIENT___BENCH___NON_BILLABLE NOT IN ('Không phải thanh toán', 'Không thanh toán', 'Không thanh toán', 'Ghế dài - SC đã hoàn tất việc thuê chiến lược ',' dự án dự phòng / Hoa Kỳ ') và DATEDIFF (CURDATE (), TARGET_FILL_DATE) <60 và DATEDIFF (CURDATE (), TARGET_FILL_DATE)> 0
Praneet Bahadur

121

Điều này tương tự như của Adam Robinson, nhưng sử dụng ISNULL thay vì COUNT.

SELECT ISNULL(
(SELECT 1 FROM Sites S
WHERE S.Id = @SiteId and S.Status = 1 AND 
      (S.WebUserId = @WebUserId OR S.AllowUploads = 1)), 0)

Nếu truy vấn bên trong có một hàng phù hợp, thì 1 được trả về. Truy vấn bên ngoài (với ISNULL) sau đó trả về giá trị này là 1. Nếu truy vấn bên trong không có hàng phù hợp, thì nó không trả về bất kỳ thứ gì. Truy vấn bên ngoài xử lý điều này giống như một NULL, và vì vậy ISNULL kết thúc trả về 0.


2
Cảm ơn bạn đã thêm cái này! Đó chính xác là thứ tôi cần, vì tôi chỉ có thể CHỌN ISNULL ((CHỌN Id ... thay vì 1 để lấy dữ liệu tôi đang tìm kiếm!
Jesse Smith

3
Rất muộn, tôi biết, nhưng bạn có thể thay thế ISNULL bằng COALESCE để đạt được kết quả tương tự.
BlueChippy

2
Tôi có thói quen sử dụng COALESCE thay vì ISNULL bởi vì từ bộ nhớ (thói quen chết dần đi), ISNULL không khả dụng trong SQL Lite hoặc bất cứ thứ gì được gọi là chạy trên các thiết bị Windows Mobile cũ hơn. COALESCE hoạt động trên cả SQL Lite, Express và SQL đầy đủ.
Quảng cáo

1
Nó hoạt động tốt hơn, nếu bạn muốn nhận giá trị biến, thay vì 0 hoặc 1. Truy vấn của Adam yêu cầu nhóm hoặc tương tự như vậy.
Drac

@MoeSisko Tôi thích cách nó trả về 0 nếu nó là null, nhưng thay vì trả về 1, làm cách nào để tôi có thể trả về giá trị từ bảng?
Michael

21

Đây có thể là một con ngựa chết, một cách khác để trả về 1 hàng khi không có hàng nào tồn tại là UNION một truy vấn khác và hiển thị kết quả khi không tồn tại trong bảng.

SELECT S.Status, COUNT(s.id) AS StatusCount
FROM Sites S
WHERE S.Id = @SiteId
GROUP BY s.Status
UNION ALL --UNION BACK ON TABLE WITH NOT EXISTS
SELECT 'N/A' AS Status, 0 AS StatusCount
WHERE NOT EXISTS (SELECT 1
   FROM Sites S
   WHERE S.Id = @SiteId
) 

2
Tôi đã sử dụng một phương pháp tương tự khi cố gắng lấy tổng từ một truy vấn. Tôi chỉ đơn giản thực hiện một kết hợp với truy vấn trả về 0 ( SELECT 0), sau đó tôi đã thực hiện một SUMtrên liên kết. Đơn giản và dễ làm theo.
cjbarth

2
Nếu nó trả về 2 hàng, nó có đảm bảo các hàng sẽ được trả về theo thứ tự mong đợi không?
Sarsaparilla

Và nó nặng về kế hoạch thực hiện
Fandango68

12

Cái gì đó như:

if exists (select top 1 * from Sites S where S.Id IS NOT NULL AND S.Status = 1 AND (S.WebUserId = @WebUserId OR S.AllowUploads = 1))
    select 1
else
    select 0

Tôi đã sử dụng giải pháp này vì nó có ý nghĩa hơn đối với tôi (theo truyền thống tôi không phải là người dùng SQL), Tuy nhiên, tôi đang sử dụng SQL Server, tôi thấy rằng việc thêm tên col vào giải pháp này đã làm tròn một cách độc đáo. tức là sau khi bạn select 1select 2tôi đã thêmas <colName>
Harvey

8

Tôi đã đọc tất cả các câu trả lời ở đây và phải mất một lúc để tìm hiểu điều gì đang xảy ra. Sau đây là câu trả lời của Moe Sisko và một số nghiên cứu liên quan

Nếu truy vấn SQL của bạn không trả về bất kỳ dữ liệu nào thì không có trường có giá trị null vì vậy cả ISNULL và COALESCE sẽ không hoạt động như bạn muốn. Bằng cách sử dụng truy vấn phụ, truy vấn cấp cao nhất nhận được một trường có giá trị null và cả ISNULL và COALESCE sẽ hoạt động như bạn muốn / mong đợi.

Sự truy vấn của tôi

select isnull(
 (select ASSIGNMENTM1.NAME
 from dbo.ASSIGNMENTM1
 where ASSIGNMENTM1.NAME = ?)
, 'Nothing Found') as 'ASSIGNMENTM1.NAME'

Truy vấn của tôi với nhận xét

select isnull(
--sub query either returns a value or returns nothing (no value)
 (select ASSIGNMENTM1.NAME
 from dbo.ASSIGNMENTM1
 where ASSIGNMENTM1.NAME = ?)
 --If there is a value it is displayed 
 --If no value, it is perceived as a field with a null value, 
 --so the isnull function can give the desired results
, 'Nothing Found') as 'ASSIGNMENTM1.NAME'

5

Bạn chỉ phải thay thế WHERE bằng THAM GIA TRÁI:

SELECT  CASE
        WHEN S.Id IS NOT NULL AND S.Status = 1 AND ...) THEN 1
        ELSE 0
    END AS [Value]

    FROM (SELECT @SiteId AS Id) R
    LEFT JOIN Sites S ON S.Id = R.Id

Giải pháp này cũng cho phép bạn trả về các giá trị mặc định cho mỗi cột, ví dụ:

SELECT
    CASE WHEN S.Id IS NULL THEN 0 ELSE S.Col1 END AS Col1,
    S.Col2,
    ISNULL(S.Col3, 0) AS Col3
FROM
    (SELECT @Id AS Id) R
    LEFT JOIN Sites S ON S.Id = R.Id AND S.Status = 1 AND ...

4

Không có bản ghi nào phù hợp có nghĩa là không có bản ghi nào được trả lại. Không có chỗ cho "giá trị" của 0 nếu không tìm thấy bản ghi nào. Bạn có thể tạo một truy vấn UNION điên rồ để làm những gì bạn muốn nhưng tốt hơn rất nhiều chỉ đơn giản là để kiểm tra số lượng bản ghi trong tập kết quả.


Hiện tại, đó là những gì tôi làm. Kiểm tra số lượng bản ghi trống hay không. Chúng có thể là một cách để viết tắt séc của tôi.
Matt

Một số ứng dụng không cho phép bạn kiểm tra "đơn giản"
Nadia Solovyeva

3

Đây có thể là một cách.

SELECT TOP 1 [Column Name] FROM (SELECT [Column Name] FROM [table]
    WHERE [conditions]
    UNION ALL
    SELECT 0 )A ORDER BY [Column Name] DESC

Tôi thích cách tiếp cận này. Tôi cảm thấy nó gọn gàng hơn một chút khi thể hiện dữ liệu mặc định, đặc biệt nếu bạn kết thúc với nhiều cột dữ liệu / giá trị mặc định.
Đánh dấu tại Ramp51

Lol đây là giải pháp tốt nhất và sạch nhất
Kyle Bridenstine

1

Còn với TIES thì sao?

SELECT TOP 1 WITH TIES tbl1.* FROM 
        (SELECT CASE WHEN S.Id IS NOT NULL AND S.Status = 1 
                      AND (S.WebUserId = @WebUserId OR 
                           S.AllowUploads = 1)
                     THEN 1 
                     ELSE 0 AS [Value]
         FROM Sites S
         WHERE S.Id = @SiteId) as tbl1
ORDER BY tbl1.[Value]

1
DECLARE @col int; 
select @col = id  FROM site WHERE status = 1; 
select coalesce(@col,0);

0

Câu trả lời của @ hai-phan sử dụng LEFT JOINlà chìa khóa, nhưng có thể hơi khó theo dõi. Tôi đã có một truy vấn phức tạp mà cũng có thể không trả lại gì. Tôi chỉ đơn giản hóa câu trả lời của anh ấy cho nhu cầu của tôi. Rất dễ áp ​​dụng cho truy vấn có nhiều cột.

;WITH CTE AS (
  -- SELECT S.Id, ...
  -- FROM Sites S WHERE Id = @SiteId
  -- EXCEPT SOME CONDITION.
  -- Whatever your query is
)
SELECT CTE.* -- If you want something else instead of NULL, use COALESCE.
FROM (SELECT @SiteId AS ID) R
LEFT JOIN CTE ON CTE.Id = R.ID

Cập nhật: Câu trả lời này trên SqlServerCentral là tốt nhất. Nó sử dụng tính năng này của MAX - "MAX trả về NULL khi không có hàng để chọn."

SELECT ISNULL(MAX(value), 0) FROM table WHERE Id = @SiteId

0
You should avoid using expensive methods. You dont need any column for TBL2. 

SELECT COUNT(*) FROM(
         SELECT TOP 1     1 AS CNT  FROM  TBL1 
         WHERE ColumnValue ='FooDoo'  ) AS TBL2

or

IF EXISTS (SELECT TOP 1 1 FROM TABLE1 AS T1 
                          WHERE T1.ColumnValue='VooDoo') 
   SELECT 1 
ELSE 
   SELECT 0
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.