find the missing values from a set of values, using SQL

时间秒杀一切 提交于 2019-12-23 22:15:16

问题


How can I find a missing values from a set of values, using SQL (Oracle DB) e.g.

SELECT NAME
FROM ACCOUNT
WHERE ACCOUNT.NAME IN ('FORD','HYUNDAI','TOYOTA','BMW'...)

(The "IN" clause may contain hundreds of values) If 'HYUNDAI' is missing in the ACCOUNT table, I need to get the result as "HYUNDAI".

Currently I use the result of the above query to do a Vlookup against the original set of values to find the missing values, I want to directly get the missing values without doing the Vlookup.

Thanks Kiran,


回答1:


You got it reversed. Do this: http://www.sqlfiddle.com/#!2/09239/3

SELECT Brand
FROM 
(
    -- Oracle can't make a row without a table, need to use DUAL dummy table
    select 'FORD' as Brand from dual union
    select 'HYUNDAI' from dual union
    select 'TOYOTA' fom dual union
    select 'BMW' from dual      
) x
where Brand not in (select BrandName from account)

Sample Account data:

create table account(AccountId int, BrandName varchar(10));

insert into account(AccountId, BrandName) values
(1,'FORD'),
(2,'TOYOTA'),
(3,'BMW');

Output:

|   BRAND |
-----------
| HYUNDAI |

Better yet, materialized the brands to a table:

select *
from Brand
where BrandName not in (select BrandName from account)

Output:

| BRANDNAME |
-------------
|   HYUNDAI |

Sample data and live test: http://www.sqlfiddle.com/#!2/09239/1

CREATE TABLE Brand
    (`BrandName` varchar(7));

INSERT INTO Brand
    (`BrandName`)
VALUES
    ('FORD'),
    ('HYUNDAI'),
    ('TOYOTA'),
    ('BMW');


create table account(AccountId int, BrandName varchar(10));

insert into account(AccountId, BrandName) values
(1,'FORD'),
(2,'TOYOTA'),
(3,'BMW');



回答2:


You should use Except: EXCEPT returns any distinct values from the left query that are not also found on the right query.

WITH SomeRows(datacol) --It will look for missing stuff here
AS( SELECT *
    FROM (  VALUES  ('FORD'),
                    ('TOYOTA'), 
                    ('BMW') 
                    ) AS F (datacol)),
AllRows (datacol) --This has everthing
AS( SELECT *
    FROM (  VALUES  ('FORD'),
                    ('HYUNDAI'),
                    ('TOYOTA'), 
                    ('BMW') 
                    ) AS F (datacol))
SELECT datacol
FROM AllRows 
EXCEPT 
SELECT datacol 
FROM SomeRows



回答3:


You can do:

SELECT a.val
FROM
(
    SELECT 'FORD' val    UNION ALL
    SELECT 'HYUNDAI'     UNION ALL
    SELECT 'TOYOTA'      UNION ALL
    SELECT 'BMW'         UNION ALL
    etc...
    etc...
) a
LEFT JOIN account b ON a.val = b.name
WHERE b.name IS NULL



回答4:


This worked perfectly, thanks Michael.

SELECT Brand
FROM 
(    -- Oracle can't make a row without a table, need to use DUAL dummy table
    select 'FORD' as Brand from dual union
    select 'HYUNDAI' from dual union
    select 'TOYOTA' fom dual union
    select 'BMW' from dual      
)
where Brand not in (select BrandName from account)

Luxspes and Zane thank you for your inputs




回答5:


Contributing Excel code to make the typing of the answer easier:

Say column A has the values (Ford, Hyundai,...).

In column B, put this in every cell:

select 'x' as brand from dual union

In column C, write this formula, and copy it down.

=REPLACE(A2,9,1,A1)

All of the select/union statements should appear in column C.



来源:https://stackoverflow.com/questions/11464543/find-the-missing-values-from-a-set-of-values-using-sql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!